PTA 關鍵活動 (30 分)
阿新 • • 發佈:2018-12-22
2.程式碼:
#include <iostream> #include<bits/stdc++.h> using namespace std; #define INF 0x3f3f3f3f const int maxn = 100 + 7; struct Edge{ int from,to,next,time,id; }edge[maxn*1000],edge2[maxn*1000]; int n,m,tot,tot2,head[maxn],in[maxn],ve[maxn],out[maxn],head2[maxn],vl[maxn],Max; void addEdge(int a,int b,int c,int d){ edge[tot].id = d;edge[tot].from = a;edge[tot].to = b;edge[tot].time = c;edge[tot].next = head[a],head[a] = tot++; } void addEdge2(int a,int b,int c){ edge2[tot2].from = a;edge2[tot2].to = b;edge2[tot2].time = c;edge2[tot2].next = head2[a],head2[a] = tot2++; } struct Node{ int s,e,id; bool operator <(const Node &another)const{ if(s==another.s)return id < another.id; return s > another.s; } Node(int a,int b,int c):s(a),e(b),id(c) {} }; bool TupoSort(){ queue<int> que; memset(ve,0,sizeof(ve)); for(int i = 1;i<=n;i++){ if(in[i]==0)que.push(i); //cout<<ve[i]<<" "<<in[i]<<endl; } int cnt = 0; while(!que.empty()){ cnt++; int p = que.front(); que.pop(); for(int i = head[p];~i;i = edge[i].next){ in[edge[i].to]--; if(ve[edge[i].to] < ve[p] + edge[i].time){ ve[edge[i].to] = ve[p] + edge[i].time; } if(!in[edge[i].to])que.push(edge[i].to); } } if(cnt!=n)return false; return true; } void ReTupoSort(){ memset(vl,INF,sizeof(vl)); queue<int> que; for(int i = 1;i<=n;i++){ if(out[i]==0){ que.push(i); vl[i] = Max; } } while(!que.empty()){ int p = que.front(); que.pop(); for(int i = head2[p];~i;i = edge2[i].next){ out[edge2[i].to]--; if(vl[edge2[i].to] > vl[p] - edge2[i].time){ vl[edge2[i].to] = vl[p] - edge2[i].time; } if(!out[edge2[i].to])que.push(edge2[i].to); } } } int main() { tot = tot2 = 0; memset(head,-1,sizeof(head)); memset(head2,-1,sizeof(head2)); memset(in,0,sizeof(in)); memset(out,0,sizeof(out)); scanf("%d%d",&n,&m); for(int i = 0;i<m;i++){ int a,b,v; scanf("%d%d%d",&a,&b,&v); addEdge(a,b,v,i); addEdge2(b,a,v); in[b]++; out[a]++; } if(!TupoSort())printf("0\n"); else{ Max = -1; for(int i = 1;i<=n;i++){ if(out[i]==0)Max = max(Max,ve[i]); } printf("%d\n",Max); ReTupoSort(); priority_queue<Node> que; for(int i = 1;i<=n;i++){ if(ve[i]!=vl[i])continue; for(int j = head[i];~j;j = edge[j].next){ if(ve[i]==vl[edge[j].to] - edge[j].time){ que.push(Node(i,edge[j].to,edge[j].id)); } } } while(!que.empty()){ Node node = que.top(); que.pop(); printf("%d->%d\n",node.s,node.e); } } }