标签:
题意:给定N个点和M条边,点编号是1到N。现在要从2到N-1中选择一个删除,同时跟选择的点连接的边也就消失,然后使得点1到N的最短路径的长度最大。如果点1和点N不连通,则输出“Inf"。
思路:直接暴力,枚举删去的点即可。我做了一步优化,只删原图最短路上的点, 所以用floyd的时候记录路径即可
//Accepted 1164 KB 0 ms #include<cstdio> #include<iostream> #include<cstring> #include<algorithm> using namespace std; #define M 1010 #define N 35 #define inf 0x3f3f3f3f int mapp[N][N],grap[N][N]; int path[N][N]; int n,m,ans; bool vis[N]; void ini(){ for(int i=1;i<=30;i++) for(int j=1;j<=30;j++){ path[i][j]=j; grap[i][j]= i==j? 0:inf; } // ans=-1; memset(vis,0,sizeof(vis)); } int main(){ while(scanf("%d%d",&n,&m),n+m){ ini(); while(m--){ int a,b,c; scanf("%d%d%d",&a,&b,&c); grap[a][b]=grap[b][a]=c; } for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) mapp[i][j]=grap[i][j]; for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++){ if(mapp[i][j]>mapp[i][k]+mapp[k][j]){ mapp[i][j]=mapp[i][k]+mapp[k][j]; path[i][j]=path[i][k]; } } ans=mapp[1][n]; for(int u=path[1][n];u!=n;u=path[u][n]){ vis[u]=1; } for(int v=1;v<=n;v++){ if(!vis[v]) continue; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) mapp[i][j]=grap[i][j]; for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(k!=v&&j!=v&&i!=v) mapp[i][j]=min(mapp[i][j],mapp[i][k]+mapp[k][j]); ans=max(ans,mapp[1][n]); if(ans==inf) break; } if(ans==inf) puts("Inf"); else printf("%d\n",ans); } return 0; }
HDU 5137 How Many Maos Does the Guanxi Worth(floyd记录路径)
标签:
原文地址:http://blog.csdn.net/kalilili/article/details/44063423