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