86 lines
2.3 KiB
C++
86 lines
2.3 KiB
C++
#include <iostream>
|
|
#include <vector>
|
|
#include <queue>
|
|
#include <algorithm>
|
|
|
|
using namespace std;
|
|
|
|
int main(){
|
|
int n, m;
|
|
while(cin >> n >> m) {
|
|
vector<vector<pair<int, int>>> adj(n + 1);
|
|
vector<int> degree(n + 1, 0);
|
|
vector<pair<pair<int, int>, int>> edges;
|
|
queue<int> q;
|
|
vector<int> topo;
|
|
vector<int> ve(n + 1, 0);
|
|
for(int i = 0; i < m; i++) {
|
|
int a, b, w;
|
|
cin >> a >> b >> w;
|
|
a--; b--;
|
|
adj[a].push_back(make_pair(b, w));
|
|
degree[b]++;
|
|
edges.push_back(make_pair(make_pair(a, b), w));
|
|
}
|
|
for(int i = 0; i < n; i++) {
|
|
if(degree[i] == 0) {
|
|
q.push(i);
|
|
}
|
|
}
|
|
while(!q.empty()) {
|
|
int u = q.front();
|
|
q.pop();
|
|
topo.push_back(u);
|
|
for(auto [v, w] : adj[u]) {
|
|
degree[v]--;
|
|
if(degree[v] == 0) {
|
|
q.push(v);
|
|
}
|
|
}
|
|
}
|
|
//topo为拓扑排序
|
|
if(topo.size() != n) {
|
|
cout << "unworkable project" << endl;
|
|
continue;
|
|
}
|
|
//正向一次,求出最早开始时间
|
|
for(int i = 0; i < topo.size(); i++) {
|
|
int u = topo[i];
|
|
for(auto [v, w] : adj[u]) {
|
|
ve[v] = max(ve[v], ve[u] + w);
|
|
}
|
|
}
|
|
int max_ve = 0;
|
|
for(int i = 0; i < n; i++) {
|
|
max_ve = max(max_ve, ve[i]);
|
|
}
|
|
//反向一次,求出最晚开始时间
|
|
vector<int> vl(n + 1, max_ve);
|
|
for(int i = topo.size() - 1; i >= 0; i--) {
|
|
int u = topo[i];
|
|
for(auto [v, w] : adj[u]) {
|
|
vl[u] = min(vl[u], vl[v] - w);
|
|
}
|
|
}
|
|
|
|
cout << max_ve << endl;
|
|
|
|
//判断是否关键路径
|
|
vector<pair<int, int>> is_critical;
|
|
for(auto e : edges) {
|
|
int a = e.first.first;
|
|
int b = e.first.second;
|
|
int w = e.second;
|
|
if(ve[a] + w == vl[b]) {
|
|
is_critical.push_back(make_pair(a, b));
|
|
}
|
|
}
|
|
sort(is_critical.begin(), is_critical.end());
|
|
for(auto [a, b] : is_critical) {
|
|
a++; b++;
|
|
cout << a << "->" << b << endl;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
} |