4 5 1 2 3 1 3 7 1 4 50 2 3 4 3 4 2 3 2 1 2 30 2 3 10 0 0
50 Inf
题意为有n个点(编号1-n),和m个关系组成的网络,默认情况下,总有一条路可以从1到达n,我们要做的就是去掉一个除了1和n之外的其他任何一个点,看能不能使得从1不能到达n,如果不能到达,就输出Inf就可以了,如果去掉任何一个点后都可以使得从1到达n,那么就输出这些最短路径中的最大的最短路径。
n最大为30,枚举每个点(1和n除外),删除该点求最短路径,可以求得 n-2个最短路径的值,如果发现有一种情况不能到达n,那么就输出Inf,否则输出这n-2个最短路径的值的最大值。
一开始按的是单向边做的,WA了两三次,后来又看了一遍题意,结果应该是双向边才可以。。。。一定要先弄清楚题意!
代码:
#include <iostream> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <algorithm> #include <vector> #include <queue> #include <stack> #include <map> #include <set> #include <cmath> #include <time.h> #include <iomanip> #include <cctype> using namespace std; #define ll long long const int maxn=32; const int inf=0x3f3f3f3f; int n,m;//节点数,有向边个数 int mp[maxn][maxn]; int dis[maxn]; bool vis[maxn]; bool ok; void dijkstra(int start,int del) { memset(dis,inf,sizeof(dis)); memset(vis,0,sizeof(vis)); dis[start]=0; for(int i=1;i<=n;i++) { if(i==del) continue; int k,Min=inf; for(int j=1;j<=n;j++) { if(dis[j]<Min&&!vis[j]) { Min=dis[j]; k=j; } } vis[k]=1; for(int j=1;j<=n;j++) { if(j==del) continue; if(dis[k]+mp[k][j]<dis[j]) dis[j]=dis[k]+mp[k][j]; } } } int main() { while(scanf("%d%d",&n,&m)!=EOF&&(n||m)) { int from,to,w; memset(mp,inf,sizeof(mp)); for(int i=1;i<=m;i++) { scanf("%d%d%d",&from,&to,&w); if(w<mp[from][to]) { mp[from][to]=w; mp[to][from]=w; } } ok=0;//判断去掉一个点能不能使得图不连通 int ans=-1; for(int i=2;i<=n-1;i++) { dijkstra(1,i);//枚举去掉的那一个点,求最短路 if(dis[n]==inf) ok=1; if(ans<dis[n])//求最短路最长的那一条 ans=dis[n]; } if(ok==1) { printf("Inf\n"); continue; } printf("%d\n",ans); } return 0; }
先用DFS判断一下能不能从1到n
#include <algorithm> #include <vector> #include <queue> #include <stack> #include <map> #include <set> #include <cmath> #include <time.h> #include <iomanip> #include <cctype> using namespace std; #define ll long long const int maxn=32; const int inf=0x3f3f3f3f; int n,m;//节点数,有向边个数 int mp[maxn][maxn]; int dis[maxn]; bool vis[maxn]; bool ok; void dijkstra(int start,int del) { memset(dis,inf,sizeof(dis)); memset(vis,0,sizeof(vis)); dis[start]=0; for(int i=1;i<=n;i++) { if(i==del) continue; int k,Min=inf; for(int j=1;j<=n;j++) { if(dis[j]<Min&&!vis[j]) { Min=dis[j]; k=j; } } vis[k]=1; for(int j=1;j<=n;j++) { if(j==del) continue; if(dis[k]+mp[k][j]<dis[j]) dis[j]=dis[k]+mp[k][j]; } } } void dfs(int s,int k) { vis[s]=1; for(int i=1;i<=n;i++) { if(!vis[i]&&i!=k&&mp[s][i]!=inf) dfs(i,k); } } int main() { while(scanf("%d%d",&n,&m)!=EOF&&(n||m)) { int from,to,w; memset(mp,inf,sizeof(mp)); for(int i=1;i<=m;i++) { scanf("%d%d%d",&from,&to,&w); if(w<mp[from][to]) { mp[from][to]=w; mp[to][from]=w; } } ok=0;//判断去掉一个点能不能使得图不连通 int ans=-1; for(int i=2;i<=n-1;i++) { memset(vis,0,sizeof(vis)); dfs(1,i); if(vis[n]==0) { ok=1; break; } dijkstra(1,i);//枚举去掉的那一个点,求最短路 if(ans<dis[n])//求最短路最长的那一条 ans=dis[n]; } if(ok==1) { printf("Inf\n"); continue; } printf("%d\n",ans); } return 0; }
[ACM] HDU 5137 How Many Maos Does the Guanxi Worth(去掉一个点使得最短路最大化)
原文地址:http://blog.csdn.net/sr_19930829/article/details/42076549