PAT--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, and L[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 4Sample Output 1:
18Sample Input 2:
4 5 0 1 1 0 2 2 2 1 3 1 3 4 3 2 5
Impossible
典型的拓撲排序,可是很久沒刷過類似的題了。還是有必要好好研究研究。
重點就在於,拓撲排序過程中如何記錄cost,以及如果有多個重點最後輸出何值。
解決方法是,在要刪掉某個可以拿出來的節點時,修正這條節點(front)指向的節點(i)的cost值cost[i]=max(cost[i],cost[front]+info[front][i]);
最後輸出出度為零的節點中耗時最多的節點cost。其實單純輸出最大值也行。
#include<stdio.h> #define num 100 #include<queue> using namespace std; //節點個數,邊數 int N,M; //bool isin[num]; //入度,出度,每個節點需要花費時間,節點之間關係矩陣 int indgree[num]; int outdegree[num]; int cost[num]; int info[num][num]; //初始化, void init(){ int i,j; for(i=0;i<num;i++){ for(j=0;j<num;j++){ info[i][j]=-1; } indgree[i]=0; outdegree[i]=0; cost[i]=0; } } //求最大值 int max(int x,int y){ return x>y?x:y; } //主方法 int solve(){ int n=0; int i,front; queue<int> Q; for(i=0;i<N;i++){ if(indgree[i]==0){ //入度為0的節點入隊。 Q.push(i); //讓其不再是0,否則會影響後面的入隊 indgree[i]--; } } //Q不空則迴圈, while(!Q.empty()){ front=Q.front(); Q.pop(); n++;//記錄現在有多少節點出隊 //出隊的都是可以抹掉的節點 for(i=0;i<N;i++){ if(info[front][i]>=0){//如果要抹掉的節點與某個節點有一條有向邊, //該邊入度減一,計算該邊的cost indgree[i]--; cost[i]=max(cost[i],cost[front]+info[front][i]); } } //重新尋找需要入隊的 for(i=0;i<N;i++){ if(indgree[i]==0){ Q.push(i); indgree[i]--; } } } //如果刪掉N個邊說明沒有環,注意cost[front]不是最終結果 if(n==N)return cost[front]; //否則 return -1; } int main(){ int file=0; FILE* fp; init(); int i,temp1,temp2,temp3; if(file){ fp=fopen("1.txt","r"); if(fp==NULL){ puts("ERROR!"); } fscanf(fp,"%d%d",&N,&M); for(i=0;i<M;i++){ fscanf(fp,"%d%d%d",&temp1,&temp2,&temp3); info[temp1][temp2]=temp3; indgree[temp2]++; outdegree[temp1]++; //printf("%d,%d,%d\n",temp1,temp2,info[temp1][temp2]); } } else{ scanf("%d%d",&N,&M); for(i=0;i<M;i++){ scanf("%d%d%d",&temp1,&temp2,&temp3); info[temp1][temp2]=temp3; indgree[temp2]++; outdegree[temp1]++; } } int res; res=solve(); if(res==-1){ puts("Impossible"); } else{ for(i=0;i<N;i++){ if(outdegree[i]==0) //可能有多個終點,需要找到耗時最多的那個 res=max(cost[i],res); } printf("%d\n",res); } return 0; }