传送门:51nod 1649
题目大意:
在有铁轨直接相连的城市之间可以跑火车,在没有铁轨直接相连的城市之间可以修公路跑汽车。在两者不同时到达同一个城市的前提下,问汽车和火车从城市 1 到城市 n 走最优路的最大值是多少。
思路:
其实这道题不难了,就是想骗下访问量……由于是没有铁轨直接相连的城市间可以修公路,所以两个城市之间要么有铁路,要么有公路。很明显,汽车和火车不会同时停靠在同一个城市。
所以,可以用 dijkstra算法跑两边最短路,先对火车求最短路,然后对汽车求最短路,然后取最大值就可以了。
值得注意的是,m=0 时要输出 -1,否则会 RE。另外输出 -1 的情况就是火车到达不了 n 或者没有公路(有 (n*(n-1))/2 条边)的情况。
代码:
#include<stdio.h>
#include<string.h>
#define inf 0x3f3f3f3f
int n,m;
int dis[404],vis[404],mp[404][404];
int dijkstra(int v)
{
int i,j,min,pos;
memset(vis,0,sizeof(vis)); //全标记为未处理
for(i=1;i<=n;i++) //dis[i]表示当前节点与i的路径长度,初始化为最大
dis[i]=mp[v][i];
dis[v]=0;
vis[v]=1;
//算法核心代码
for(i=1;i<n;i++)
{ //进行n-1次处理
min=inf;
for(j=1;j<=n;j++) //寻找未处理的点中路径最短的
if(!vis[j] && dis[j]<min)
{
min=dis[j];
pos=j;
}
vis[pos]=1;
for(j=1;j<=n;j++) //用该节点更新其他未处理节点的最短路径
if(!vis[j]&&dis[j]>dis[pos]+mp[pos][j])
dis[j]=dis[pos]+mp[pos][j];
}
}
int main()
{
int i,j,u,v,ans;
while(~scanf("%d%d",&n,&m))
{
if(m==0)
{ //特判
printf("-1\n");
continue;
}
memset(mp,inf,sizeof(mp)); //初始化为最大值
for(i=0;i<m;i++)
{
scanf("%d%d",&u,&v);
mp[u][v]=1;
mp[v][u]=1;
}
dijkstra(1); //先求火车的最短路
ans=dis[n];
if(ans==inf||m==(n*(n-1))/2)
{ //如果火车不能到达或者没有公路
printf("-1\n");
continue;
}
for(i=1;i<=n;i++) //要么是公路要么是铁路
for(j=1;j<=n;j++) //把铁路去掉换成公路
if(mp[i][j]==inf&&i!=j) mp[i][j]=1;
else mp[i][j]=inf;
dijkstra(1); //求公路的最短路
if(dis[n]>ans) ans=dis[n]; //取最大值
printf("%d\n",ans);
}
return 0;
}