Uva10806
这题是要你求从顶点1到顶点n然后再从n到1的最小的花费,注意两次走的边不能有相同的。。。原本单蠢的以为求一遍最短路,然后把边给删掉。。然后在跑一遍。后来想想不行啊,这样第一次的最短路会造成第二次回去无路可走。
其实关键是在求第二次的最短路的时候我们要对图进行一下处理,把无向图转变为有向图。我们先把一个次走过的边的权值变成0,然后再把它的反向变的权值转为相反数。这样两次一定要走的路的权值就会抵消掉,相当于没走= =
#include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> const int N=110; #define inf 9999999 #include<queue> using namespace std; int d[N],p[N];//p数组记录的是前驱顶点 int g[N][N]; int n; int spfa() { for(int i=0;i<=n;i++) d[i]=inf; d[1]=0; queue<int>q; q.push(1); while(!q.empty()) { int u=q.front(); q.pop(); for(int v=1;v<=n;v++) { if(g[u][v]&&d[v]>d[u]+g[u][v]) { d[v]=d[u]+g[u][v]; p[v]=u; q.push(v); } } } if(d[n]==inf) return 1; else return 0; } int main() { int m; while(scanf("%d",&n)!=EOF&&n) { memset(g,0,sizeof(g)); scanf("%d",&m); int a,b,c; while(m--) { scanf("%d %d %d",&a,&b,&c); g[a][b]=g[b][a]=c; } int ans=0; if(spfa()) { printf("Back to jail\n"); } else { ans+=d[n]; for(int i=n;i!=1;i=p[i]) { g[p[i]][i]=0; g[i][p[i]]=-g[i][p[i]]; } if(spfa()) printf("Back to jail\n"); else printf("%d\n",ans+d[n]); } } return 0; }