题目地址:http://codeforces.com/contest/602/problem/C
题意:首先输入n,m。n代表一开始有个包含n个节点的完全图。之后m行有m条边是属于铁路的,那么完全图中的其他路就是属于公路的了。求点1到点n。铁路和公路都可以到达n点,而且走铁路和走公路不可以同时经过相同的节点(终点除外)时的铁路和公路到达n的时间中大的一个时间的最小值。至少有一条路不能到达终点则输出-1
题解:很容易发现,因为原来是一个完全图,所以必定有1-n的一条边分配给了铁路或者公路。那么没有分配到这条边的路,求一下最短路就可以了。这样是保证中途不会有相同的节点同时到达的。也就是输出max(铁路到n的最短路长度,公路到n的最短路长度)
#include <cstdio>
#include <algorithm>
#include <queue>
#include <vector>
#include <cmath>
#include <cstring>
#define N 410
#define INF 100010
typedef long long ll;
using namespace std;
vector<int>v[N];
vector<int>v1[N];
int dist[N],dist1[N];
int visit[N];
int mapn[N][N];
int n,m;
void spfa() //SPFA算法
{
int i, now;
memset(visit, false, sizeof(visit));
for(i = 1; i <= n; i++) dist[i] = INF;
dist[1] = 0;
queue<int> Q;
Q.push(1);
visit[1] = true;
while(!Q.empty())
{
now = Q.front();
Q.pop();
visit[now] = false;
int tmp=v[now].size();
for(i=0;i<tmp;i++)
{
int t=v[now][i];
if(dist[t] > dist[now] + 1)
{
dist[t] = dist[now] + 1;
if(visit[t] == 0)
{
Q.push(t);
visit[t] = true;
}
}
}
}
}
void spfa1() //SPFA算法
{
int i, now;
memset(visit, false, sizeof(visit));
for(i = 1; i <= n; i++) dist1[i] = INF;
dist1[1] = 0;
queue<int> Q;
Q.push(1);
visit[1] = true;
while(!Q.empty())
{
now = Q.front();
Q.pop();
visit[now] = false;
int tmp=v1[now].size();
for(i=0;i<tmp;i++)
{
int t=v1[now][i];
if(dist1[t] > dist1[now] + 1)
{
dist1[t] = dist1[now] + 1;
if(visit[t] == 0)
{
Q.push(t);
visit[t] = true;
}
}
}
}
}
int main()
{
int i;
int a,b,j;
// freopen("in.txt","r",stdin);
memset(mapn,0,sizeof(mapn));
scanf("%d%d",&n,&m);
for(i=1;i<=m;i++)
{
scanf("%d%d",&a,&b);
mapn[a][b]=mapn[b][a]=1;
v[a].push_back(b);
v[b].push_back(a);
}
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
if(i==j)
continue;
else if(mapn[i][j]==0)
{
v1[i].push_back(j);
v1[j].push_back(i);
}
}
spfa();
spfa1();
if(max(dist[n],dist1[n])==INF)
printf("-1\n");
else
printf("%d\n",max(dist[n],dist1[n]));
return 0;
}