最短工期 (25 分)
一个项目由若干个任务组成,任务之间有先后依赖顺序。项目经理需要设置一系列里程碑,在每个里程碑节点处检查任务的完成情况,并启动后续的任务。现给定一个项目中各个任务之间的关系,请你计算出这个项目的最早完工时间。
输入格式:
首先第一行给出两个正整数:项目里程碑的数量 N(≤100)和任务总数 M。这里的里程碑从 0 到 N−1 编号。随后 M 行,每行给出一项任务的描述,格式为“任务起始里程碑 任务结束里程碑 工作时长”,三个数字均为非负整数,以空格分隔。
输出格式:
如果整个项目的安排是合理可行的,在一行中输出最早完工时间;否则输出"Impossible"。
输入样例 1:
9 12
0 1 6
0 2 4
0 3 5
1 4 1
2 4 1
3 5 2
5 4 0
4 6 9
4 7 7
5 7 4
6 8 2
7 8 4
输出样例 1:
18
输入样例 2:
4 5
0 1 1
0 2 2
2 1 3
1 3 4
3 2 5
输出样例 2:
Impossible
代码:
#include<stdio.h>
int main(){
int N,E;
scanf("%d%d",&N,&E);
//邻接矩阵
int G[N][N];
//顶点度数
int d[N];
//距离(时间)存储在顶点内
int point[N];
int i,j;
//初始化:度数0,距离0,邻接矩阵-1
for(i=0;i<N;i++){
d[i] = 0;
point[i] = 0;
for(j=0;j<N;j++){
G[i][j] = -1;
}
}
//输入数据
for(i=0;i<E;i++){
int v1,v2,e;
scanf("%d%d%d",&v1,&v2,&e);
//有向图
G[v1][v2] = e;
//度数增加
d[v2]++;
}
//创建队列,并初始化
int q[100] ={0};
int front = 0,tail = 0;
//最大的距离(最早完成日期)
int max = 0;
for(i=0;i<N;i++){
if(d[i] == 0){
q[tail++] = i;
}
}
//核心思想:如果不含环,顶点数 == 尾指针;每个顶点进入队列一次
//队列为空时退出
while(front < tail){
//出队
int temp = q[front++];
//寻找temp的后面顶点,并筛选和temp有关系的顶点
for(i=0;i<N;i++){
//有关系
if(G[temp][i] != -1){
//将[开始 ---> 目前点]总距离(时间)存储在顶点内
point[i] = point[temp] + G[temp][i];
//每一次和max比较,找出最大
if(point[i] > max){
max = point[i];
}
//度数递减
d[i]--;
//当度数为0时,入队,适合本题处理顶点:4,8
if(d[i] == 0){
q[tail++] = i;
}
}
}
}
// printf("%d\n",tail);
if(tail == N){
printf("%d",max);
}else{
printf("Impossible");
}
return 0;
}