题目链接:http://soj.me/1308
题目描述:
给出N项工作,以及工作之间的依赖关系,求出第M项工作的最早完成时间。其中第i项工作依赖于第j项工作表示,完成第j项工作之后才能完成第i项工作。
算法实现:
初看这道题目,很容易和求关键路径问题中的最早完成时间混淆,但实际上题目中说到:每个单位时间只能完成一项工作,而求关键路径问题中某些工作是可以同时完成的,因此这道题目与求关键路径没有关系。当然,这道题目非常简单:要完成第M项工作,需先完成它所依赖的工作,要完成它依赖的工作,需先完成它依赖工作所依赖的工作,以此类推,容易用递归实现。工作之间的依赖关系可以用逆邻接表描述,对输入的处理细心一点就可以了。
代码实现:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#define MAXN 10001
using namespace std;
struct ArcNode
{
int tail;
ArcNode *next;
};
struct VNode
{
int time;
ArcNode *first;
};
struct Graph
{
VNode v[MAXN];
};
int n,m,sum;
Graph g;
bool finish[MAXN];
void work(int cur)
{
ArcNode *p;
for(p=g.v[cur].first;p;p=p->next)
{
if(!finish[p->tail])
work(p->tail);
}
sum+=g.v[cur].time;
finish[cur]=1;
}
/*从字符串中截取一个数字*/
int get_num(string &str)
{
while(str!=""&&(str[0]<'0'||str[0]>'9'))
str.erase(0,1);
int num=0;
while(str!=""&&str[0]>='0'&&str[0]<='9')
{
num=num*10+str[0]-'0';
str.erase(0,1);
}
while(str!=""&&(str[0]<'0'||str[0]>'9'))
str.erase(0,1);
return num;
}
int main()
{
while(cin>>n&&n>0)
{
cin>>m;
getchar();
memset(finish,0,sizeof(finish));
for(int i=1;i<=n;i++)
{
g.v[i].first=NULL;
int num;
string line;
getline(cin,line);//读取一行
num=get_num(line);
g.v[i].time=num;
while(line!="")
{
num=get_num(line);
ArcNode *tmp=new ArcNode();
tmp->tail=num;
tmp->next=g.v[i].first;
g.v[i].first=tmp;
}
}
sum=0;
work(m);
cout<<sum<<endl;
}
return 0;
}