7-12 How Long Does It Take

时间:2023-03-09 19:24:25
7-12 How Long Does It Take

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".

知识点:拓扑排序

思路:

建一个图‘pre’,记录每一个节点的前节点;建一个图‘Graph’,记录每一个节点的后节点

建一个队列,每次操作后,入度(indegree)为0的节点入队

  • 注意多个起点和终点的问题:
    • 完成后扫描最大的cost输出
  • 有回路问题
    • 遍历的节点数<总节点数,即有回路
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
const int maxn = ; int n,m;
struct edge{
int v;
int time;
};
vector<edge> pre[maxn];
vector<int> Graph[maxn];
int cost[maxn];
int indegree[maxn]; void check(int start,int end){
int cnt=;
fill(cost,cost+maxn,);
queue<int> q;
for(int i=;i<n;i++){ // indegree==0 的入队
if(indegree[i]==){
q.push(i);
}
}
int tmp;
while(q.size()){ // 按照拓扑序搜索
tmp = q.front();
cnt++;
q.pop();
cost[tmp] = ;
for(int i=;i<pre[tmp].size();i++){
if((pre[tmp][i].time+cost[pre[tmp][i].v]) > cost[tmp]){
cost[tmp] = (pre[tmp][i].time+cost[pre[tmp][i].v]);
}
}
for(int i=;i<Graph[tmp].size();i++){
indegree[Graph[tmp][i]]--;
if(indegree[Graph[tmp][i]]==){
q.push(Graph[tmp][i]);
}
}
}
int endtime = ;
if(cnt!=n) printf("Impossible\n");
else{
for(int i=;i<n;i++){
if(cost[i]>endtime){
endtime=cost[i];
}
}
printf("%d\n",endtime);
}
} int main(int argc, char *argv[]) {
scanf("%d %d",&n,&m);
int a,b,t;
struct edge newedge;
int flag[maxn];
fill(flag,flag+maxn,);
for(int i=;i<m;i++){
scanf("%d %d %d",&a,&b,&newedge.time);
indegree[b]++;
newedge.v = a;
flag[a] = ;
pre[b].push_back(newedge);
Graph[a].push_back(b);
}
int start,end;
for(int i=;i<n;i++){
if(flag[i]==){
end = i;
}
if(pre[i].size()==){
start = i;
}
}
//printf("%d %d",start,end);
check(start,end);
}

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