#include #include #include #include using namespace std; int main(){ int n, m; while(cin >> n >> m) { vector>> adj(n + 1); vector degree(n + 1, 0); vector, int>> edges; queue q; vector topo; vector 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 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> 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; }