拓扑排序系列
关键路径:证明。好吧,我果然智商地下,照着模板码都搞这么久,代码又臭又长。。
1 #include<cstdio> 2 #include<cstring> 3 #include<vector> 4 #include<algorithm> 5 #include<cstdlib> 6 #include<queue> 7 #include<stack> 8 using namespace std; 9 const int maxn = 1010; 10 const int INF = 1<<29; 11 int n,m; 12 struct Edge{ 13 int from,to,dist; 14 Edge(int from,int to,int dist):from(from),to(to),dist(dist){} 15 }; 16 17 vector<Edge> edges; 18 vector<int > G1[maxn]; 19 vector<int > G2[maxn]; 20 21 int fast[maxn]; 22 int last[maxn]; 23 int vend[maxn]; 24 int num_in[maxn]; 25 void init() 26 { 27 for(int i = 0;i <= n;i++) last[i] = INF; 28 memset(fast,0,sizeof(fast)); 29 } 30 31 void AddEdge(int from,int to,int dist) 32 { 33 edges.push_back(Edge(from,to,dist)); 34 edges.push_back(Edge(to,from,dist)); 35 int m = edges.size(); 36 G1[from].push_back(m-2); 37 G2[to].push_back(m-1); 38 } 39 40 41 void topsort() 42 { 43 queue<int> Q; 44 stack<int> S; 45 for(int i = 1;i <= n;i++) 46 if(!num_in[i]) Q.push(i); 47 int vis[maxn]; 48 memset(vis,0,sizeof(vis)); 49 while(!Q.empty()) 50 { 51 int u = Q.front();Q.pop(); 52 if(vis[u]) continue; 53 vis[u] = 1; 54 S.push(u); 55 for(int i = 0;i < G1[u].size();i++) 56 { 57 Edge& e = edges[G1[u][i]]; 58 num_in[e.to]--; 59 fast[e.to] = max(fast[e.to],fast[e.from]+e.dist); 60 if(!num_in[e.to]) 61 Q.push(e.to); 62 } 63 } 64 memset(vis,0,sizeof(vis)); 65 last[n] = fast[n]; 66 while(!S.empty()) 67 { 68 int u = S.top();S.pop(); 69 if(vis[u]) continue; 70 vis[u] = 1; 71 for(int i = 0;i < G2[u].size();i++) 72 { 73 Edge& e = edges[G2[u][i]]; 74 last[e.to] = min(last[e.to],last[e.from] - e.dist); 75 } 76 } 77 memset(vis,0,sizeof(vis)); 78 vector<int> ans; 79 for(int i = 1;i <= n-1;i++) 80 { 81 for(int j = 0;j < G1[i].size();j++) 82 { 83 Edge& e = edges[G1[i][j]]; 84 vend[e.from] = last[e.to] - e.dist; 85 if(vend[e.from] == fast[e.from]) 86 ans.push_back(G1[i][j]/2+1); 87 } 88 } 89 sort(ans.begin(),ans.end()); 90 for(int i = 0;i < ans.size();i++) 91 printf("%d\n",ans[i]); 92 } 93 int main() 94 { 95 scanf("%d%d",&n,&m); 96 init(); 97 for(int i =0 ;i < m;i++) 98 { 99 int from,to,dist; 100 scanf("%d%d%d",&from,&to,&dist); 101 num_in[to]++; 102 AddEdge(from,to,dist); 103 } 104 topsort(); 105 return 0; 106 }
呃呃呃,既然是拓扑排序系列,我就不写拓扑排序了23333

浙公网安备 33010602011771号