PAT (Advanced Level) 1018. Public Bike Management (30)
先找出可能在最短路上的边,图变成了一个DAG,然后在新图上DFS求答案就可以了。
#include<iostream> #include<cstring> #include<cmath> #include<algorithm> #include<cstdio> #include<queue> #include<vector> using namespace std; const int INF=0x7FFFFFFF; const int maxn=550; int n,m,C1,C2,tot; int Cmax; int val[maxn]; struct Edge { int u,v,L; }e[600000]; int f[600000]; vector<int>g[maxn]; int dis[2][maxn]; int ans[maxn],cnt; int sta[maxn]; int MIN1,MIN2; void init() { MIN1=MIN2=INF; tot=0;C1=0; for(int i=0;i<=500;i++) g[i].clear(); } void add(int a,int b,int c) { e[tot].u=a,e[tot].v=b,e[tot].L=c; g[a].push_back(tot); tot++; } void read() { scanf("%d%d%d%d",&Cmax,&n,&C2,&m); for(int i=1;i<=n;i++) scanf("%d",&val[i]); for(int i=1;i<=m;i++) { int u,v,L; scanf("%d%d%d",&u,&v,&L); add(u,v,L); add(v,u,L); } } void SPFA(int f,int st) { for(int i=0;i<=500;i++) dis[f][i]=INF; dis[f][st]=0; int flag[maxn]; memset(flag,0,sizeof flag); queue<int>Q; Q.push(st); flag[st]=1; while(!Q.empty()) { int head= Q.front(); Q.pop(); flag[head]=0; for(int i=0;i<g[head].size();i++) { int id=g[head][i]; if(dis[f][head]+e[id].L<dis[f][e[id].v]) { dis[f][e[id].v]=dis[f][head]+e[id].L; if(flag[e[id].v]==0) { Q.push(e[id].v); flag[e[id].v]=1; } } } } } void dfs(int x,int num1,int num2,int deep) { sta[deep]=x; if(x==C2) { if(num2<MIN2) { MIN2=num2; MIN1=num1; for(int i=0;i<=deep;i++) ans[i]=sta[i]; tot=deep; } else if(num2==MIN2&&num1<MIN1) { MIN2=num2; MIN1=num1; for(int i=0;i<=deep;i++) ans[i]=sta[i]; tot=deep; } return; } for(int i=0;i<g[x].size();i++) { if(f[g[x][i]]==0) continue; int to=e[g[x][i]].v; if(val[to]==Cmax/2) dfs(to,num1,num2,deep+1); else if(val[to]>Cmax/2) dfs(to,num1+val[to]-Cmax/2,num2,deep+1); else if(val[to]<Cmax/2) { if(num1>Cmax/2-val[to]) dfs(to,num1+val[to]-Cmax/2,num2,deep+1); else dfs(to,0,num2+Cmax/2-val[to]-num1,deep+1); } } } void work() { int len=dis[0][C2]; for(int i=0;i<tot;i++) if(dis[0][e[i].u]+e[i].L+dis[1][e[i].v]==len) f[i]=1; dfs(0,0,0,0); printf("%d ",MIN2); for(int i=0;i<=tot;i++) { if(i<tot) printf("%d->",ans[i]); else printf("%d ",ans[i]); } printf("%d\n",MIN1); } int main() { init(); read(); SPFA(0,C1); SPFA(1,C2); work(); return 0; }