Files
Data-Structure/Exercise/Homework7/Q2KahTuoPuAOE.cpp
2025-12-08 22:54:52 +08:00

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;
}