标签:
题意:给定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