简单的拓扑排序。
基础思路是这样的,对每个节点,都有一个时间参数,用来记录从起始到这个节点总共所需的最短时间。由于规矩是只有把该节点所有的入度给做完了,才能执行这个节点。所以每个节点都是等于它的入度节点的以及路径权重相加的最大值。
利用拓扑排序算法就可以做了。注意多起始节点和多终止节点怎么处理的问题。
#include <stdio.h>
#include <stdlib.h>
typedef struct _node{
int name;
int time;
struct _node *next;
}Node;
typedef struct _head{
int in;
struct _node *out;
}Head;
typedef struct _que{
int loction;
struct _que *next;
}Que;
typedef struct _table{
int know;
int stime;
}Table;
Table *Sheet;
Head *ArrayList;
int Check;
int Act;
int First;
int Last;
void add_array(Node *Beginer,int name,int time);
void print_array(Node *Beginer);
void insert_que(Que *root,int i);
int dele_que(Que *root);
void topshot();
void print_table();
void print_que(Que *root);
int main(){
scanf("%d %d",&Check,&Act);
ArrayList=(Head*)malloc(Check*sizeof(Head));
Sheet=(Table*)malloc(Check*sizeof(Table));
int i,j,t,k;
for(k=0;k<Check;k++){
ArrayList[k].in=0;
ArrayList[k].out=(Node*)malloc(sizeof(Node));
ArrayList[k].out->next=NULL;
Sheet[k].know=0;
Sheet[k].stime=0;
}
for(k=0;k<Act;k++){
scanf("%d %d %d",&i,&j,&t);
add_array(ArrayList[i].out,j,t);
ArrayList[j].in++;
if(k==0){
First=i;
}
if(k==Act-1){
Last=j;
}
}
// for(k=0;k<Check;k++){
// printf("%d: in=%d ",k,ArrayList[k].in);
// print_array(ArrayList[k].out);
// printf("\n");
// }
topshot();
// print_table();
return 0;
}
void topshot(){
Que *root=(Que*)malloc(sizeof(Que));
root->next=NULL;
int k;
int cnt=0;
for(k=0;k<Check;k++){
if(ArrayList[k].in==0){
insert_que(root,k);
cnt++;
}
}
// print_que(root);
int result;
Node *subhead;
while(1){
result=dele_que(root);
Sheet[result].know=1;
if(result==-1){
break;
}
subhead=ArrayList[result].out->next;
while(subhead){
if(Sheet[subhead->name].know==0){
--ArrayList[subhead->name].in;
if(ArrayList[subhead->name].in==0){
insert_que(root,subhead->name);
cnt++;
}
if(Sheet[result].stime+subhead->time > Sheet[subhead->name].stime){
Sheet[subhead->name].stime=Sheet[result].stime+subhead->time;
}
}
subhead=subhead->next;
}
}
if(cnt!= Check){
printf("Impossible");
}else{
int biggest=0;
for(k=0;k<Check;k++){
if(Sheet[k].stime>biggest){
biggest=Sheet[k].stime;
}
}
printf("%d",biggest);
}
}
void add_array(Node *Beginer,int name,int time){
Node *p=Beginer;
Node *q=(Node*)malloc(sizeof(Node));
q->name=name;
q->time=time;
q->next=Beginer->next;
Beginer->next=q;
}
void print_array(Node *Beginer){
Node *p=Beginer->next;
while(p){
printf("name=%d time=%d% ",p->name,p->time);
p=p->next;
}
}
void insert_que(Que *root,int i){
Que *p=root;
while(p->next){
p=p->next;
}
Que *q=(Que*)malloc(sizeof(Que));
q->loction=i;
p->next=q;
q->next=NULL;
}
int dele_que(Que *root){
Que *p=root->next;
int result=-1;
if(p){
result=p->loction;
root->next=p->next;
free(p);
}
return result;
}
void print_table(){
int k=0;
for(k=0;k<Check;k++){
printf("%d: ",k);
printf("know=%d stime=%d ",Sheet[k].know,Sheet[k].stime);
printf("\n");
}
}
void print_que(Que *root){
Que *p=root->next;
while(p){
printf("%d ",p->loction);
p=p->next;
}
printf("\n");
}
08-图8 How Long Does It Take (25分)
Given the relations of all the activities of a project, you are supposed to find the earliest completion time of the project.
Input Specification:
Each input file contains one test case. Each case starts with a line containing two positive integers N (≤100), the number of activity check points (hence it is assumed that the check points are numbered from 0 to N−1), and M, the number of activities. Then M lines follow, each gives the description of an activity. For the i
-th activity, three non-negative numbers are given: S[i]
, E[i]
, and L[i]
, where S[i]
is the index of the starting check point, E[i]
of the ending check point, andL[i]
the lasting time of the activity. The numbers in a line are separated by a space.
Output Specification:
For each test case, if the scheduling is possible, print in a line its earliest completion time; or simply output "Impossible".
Sample Input 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
Sample Output 1:
18
Sample Input 2:
4 5
0 1 1
0 2 2
2 1 3
1 3 4
3 2 5
Sample Output 2:
Impossible