How Long Does It Take
https://pintia.cn/problem-sets/16/problems/674
Description
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 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
Notes
- 存图的方法
图结构
struct edge {
ll from, to, w;
//构造函数
// e[a].push_back(edge(a, b, c)); ->对e[a]元素存入a,b,c三个值
edge(ll a, ll b, ll c) {
from = a;
to = b;
w = c;
}
};
创建图结构数组实例
vector<edge> e[maxn];
图的结点实例
vector<edge> V;
创建关于图元素数组的队列
queue<vector<edge>> Q;
Code
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define mod 1000000007
const ll maxn = 2e6 + 7;
ll n, m;
/**
* @n 顶点数
* @m 边数
*/
ll indegree[maxn];//记录入度
struct edge {
ll from, to, w;
edge(ll a, ll b, ll c) {
from = a;
to = b;
w = c;
}
};
ll Earliest[maxn];//记录最早完成的时间
vector<edge> e[maxn];
queue<vector<edge>> Q;
bool TopSort() {
for (long long i = 0; i < n; ++i) {
for (long long j = 0; j < e[i].size(); ++j) {
ll outvex = e[i][j].to;
indegree[outvex]++;
/**
* 对每个顶点遍历出边以计算每个顶点的入度
*/
}
}
for (long long i = 0; i < n; ++i) {
if (indegree[i] == 0) {
Q.push(e[i]);
Earliest[i]=0;
}
/**
* 遍历顶点,找到边数为0的顶点,这个顶点就作为起点
*/
}
ll cnt = 0;//记录输出的边数
while (!Q.empty()) {
vector<edge> V;
V = Q.front();
Q.pop();
cnt++;//无解判断变量
//输出或记录
for (long long i = 0; i < V.size(); ++i) {
ll time = V[i].w;
ll to = V[i].to;
ll fromtime = Earliest[V[i].from];
if (--indegree[to] == 0) {
Q.push(e[to]);
}
/**
* !! can not use
* @Earlist[to]=@fromtime
* @Earlist[to]+@time>@Earliset[to]
* -> let the preivous Earliest to be updated
* the preivous @Earlist[to] should be used to compare with the new values
*
*/
if (fromtime + time > Earliest[to]) {
Earliest[to] = fromtime + time;
}
}
}
if (cnt != n) return false;//图中有回路,排序失败,不满足每个元素都至少进队一次
//队列已空,但是还有元素没有进入队列
else return true;
}
int main() {
scanf("%lld%lld", &n, &m);
for (long long i = 0; i < m; ++i) {
ll a, b, c;
scanf("%lld%lld%lld", &a, &b, &c);
e[a].push_back(edge(a, b, c));
}
if (TopSort()) {
ll ans = -1;
for (long long i = 0; i < n; ++i) {
if (Earliest[i] > ans) ans = Earliest[i];
}
printf("%lld", ans);
} else {
printf("Impossible");
}
return 0;
}