PAT L3-007. 天梯地图
最短路。求出一个最短路的$DAG$,然后在$DAG$上$dp$即可。
#include<map> #include<set> #include<ctime> #include<cmath> #include<queue> #include<string> #include<stack> #include<vector> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<functional> using namespace std; int n,m,sz,s,t,now; struct X { int u,v,f,L,T; }e[5000000]; vector<int>G[600]; vector<int>FG[600]; vector<int>Top[600]; vector<int>ans1,ans2; int A1,A2; int timeS[600],timeT[600],dis[600],num[600],pre[600],f[600],In[600]; int disS[600],disT[600]; void spfaOneS() { for(int i=0;i<n;i++) timeS[i]=0x7FFFFFFF, f[i]=0; timeS[s]=0; f[s]=1; queue<int>Q; Q.push(s); while(!Q.empty()) { int h = Q.front(); Q.pop(); f[h]=0; for(int i=0;i<G[h].size();i++) { int id = G[h][i]; int to = e[id].v; if(timeS[h]+e[id].T<timeS[to]) { timeS[to] = timeS[h]+e[id].T; if(f[to]==0) { f[to]=1; Q.push(to); } } } } } void spfaOneT() { for(int i=0;i<n;i++) timeT[i]=0x7FFFFFFF, f[i]=0; timeT[t]=0; f[t]=1; queue<int>Q; Q.push(t); while(!Q.empty()) { int h = Q.front(); Q.pop(); f[h]=0; for(int i=0;i<FG[h].size();i++) { int id = FG[h][i]; int to = e[id].u; if(timeT[h]+e[id].T<timeT[to]) { timeT[to] = timeT[h]+e[id].T; if(f[to]==0) { f[to]=1; Q.push(to); } } } } } void WOne() { for(int i=0;i<n;i++) dis[i]=0x7FFFFFFF, pre[i]=-1; dis[s]=0; queue<int>Q; for(int i=0;i<n;i++) if(In[i]==0) Q.push(i); while(!Q.empty()) { int h=Q.front(); Q.pop(); for(int i=0;i<Top[h].size();i++) { int id = Top[h][i]; int to = e[id].v; if(dis[h]+e[id].L<dis[to]) { dis[to] = dis[h]+e[id].L; pre[to] = h; } In[to]--; if(In[to]==0) Q.push(to); } } } void spfaTwoS() { for(int i=0;i<n;i++) disS[i]=0x7FFFFFFF, f[i]=0; disS[s]=0; f[s]=1; queue<int>Q; Q.push(s); while(!Q.empty()) { int h = Q.front(); Q.pop(); f[h]=0; for(int i=0;i<G[h].size();i++) { int id = G[h][i]; int to = e[id].v; if(disS[h]+e[id].L<disS[to]) { disS[to] = disS[h]+e[id].L; if(f[to]==0) { f[to]=1; Q.push(to); } } } } } void spfaTwoT() { for(int i=0;i<n;i++) disT[i]=0x7FFFFFFF, f[i]=0; disT[t]=0; f[t]=1; queue<int>Q; Q.push(t); while(!Q.empty()) { int h = Q.front(); Q.pop(); f[h]=0; for(int i=0;i<FG[h].size();i++) { int id = FG[h][i]; int to = e[id].u; if(disT[h]+e[id].L<disT[to]) { disT[to] = disT[h]+e[id].L; if(f[to]==0) { f[to]=1; Q.push(to); } } } } } void WTwo() { for(int i=0;i<n;i++) num[i]=0x7FFFFFFF, pre[i]=-1; num[s]=0; queue<int>Q; for(int i=0;i<n;i++) if(In[i]==0) Q.push(i); while(!Q.empty()) { int h=Q.front(); Q.pop(); for(int i=0;i<Top[h].size();i++) { int id = Top[h][i]; int to = e[id].v; if(num[h]+1<num[to]) { num[to] = num[h]+1; pre[to] = h; } In[to]--; if(In[to]==0) Q.push(to); } } } bool check() { if(ans1.size()!=ans2.size()) return 0; for(int i=0;i<ans1.size();i++) { if(ans1[i]!=ans2[i]) return 0; } return 1; } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { scanf("%d%d%d%d%d",&e[sz].u,&e[sz].v,&e[sz].f,&e[sz].L,&e[sz].T); G[e[sz].u].push_back(sz); FG[e[sz].v].push_back(sz); sz++; if(e[sz-1].f==0) { e[sz].u = e[sz-1].v; e[sz].v = e[sz-1].u; e[sz].f = e[sz-1].f; e[sz].L = e[sz-1].L; e[sz].T = e[sz-1].T; G[e[sz].u].push_back(sz); FG[e[sz].v].push_back(sz); sz++; } } scanf("%d%d",&s,&t); spfaOneS(); spfaOneT(); A1 = timeS[t]; memset(In,0,sizeof In); for(int i=0;i<sz;i++) { if(timeS[e[i].u]+timeT[e[i].v]+e[i].T==timeS[t]) { Top[e[i].u].push_back(i); In[e[i].v]++; } } WOne(); now=t; stack<int>st; while(1) { st.push(now); now=pre[now]; if(now==-1) break; } while(!st.empty()) { ans1.push_back(st.top()); st.pop(); } spfaTwoS(); spfaTwoT(); A2 = disS[t]; for(int i=0;i<n;i++) Top[i].clear(); memset(In,0,sizeof In); for(int i=0;i<sz;i++) { if(disS[e[i].u]+disT[e[i].v]+e[i].L==disS[t]) { Top[e[i].u].push_back(i); In[e[i].v]++; } } WTwo(); now=t; while(1) { st.push(now); now=pre[now]; if(now==-1) break; } while(!st.empty()) { ans2.push_back(st.top()); st.pop(); } if(check()) { printf("Time = %d; Distance = %d:",A1,A2); for(int i=0;i<ans2.size();i++) { printf(" %d",ans2[i]); if(i<ans2.size()-1) printf(" =>"); else printf("\n"); } } else { printf("Time = %d:",A1); for(int i=0;i<ans1.size();i++) { printf(" %d",ans1[i]); if(i<ans1.size()-1) printf(" =>"); else printf("\n"); } printf("Distance = %d:",A2); for(int i=0;i<ans2.size();i++) { printf(" %d",ans2[i]); if(i<ans2.size()-1) printf(" =>"); else printf("\n"); } } return 0; }