题目描述

梦工厂有 n 个分厂(从 1 开始编号),有m对分厂通过双向铁路相连。
为了保证每两个分厂之间的同学可以方便地进行交流,掌舵人张老师就在那些没有铁路连接的分厂之间建造了公路。
在两个直接通过公路或铁路相连的分厂之间移动,需要花费 1 小时。
现在菜鸡wxy和hbz都从1厂出发,wxy开火车,hbz开汽车,各自前往n厂。但是,他们中途不能同时停在同一个分厂
(但是可以同时停在n厂)。
现在请你来为wxy和hbz分别设计一条线路,使他们尽可能快地到达n厂(即要求他们中最后到达n厂的时间最短)。
所有的公路或铁路可以被多次使用,求最短时间。(火车和汽车可以同时到达n,也可以先后到达。)

 

输入

首先有 2 个整数 n 和 m (2<=n<=500, 0<=m<=n*(n-1)/2 分别表示梦工厂分厂的数目和铁路的数目;

接下来的 m 对数字,每对由两个整数 u 和 v 构成,表示小镇 u 和小镇 v 之间有一条铁路。(u!=v  1<=u,v<=n)
输入保证无重边

 

输出

输出一个整数,表示答案,如果没有合法的路线规划,输出-1

 

样例输入

4 3
1 2
2 3
3 4

 

样例输出

3

不难发现,必有1人的最短时间是1(若有1到n的铁路,则走铁路的最短时间是1;若没有1的n的铁路,那么必有1到n的公路,则走公路的最短时间是1)

两张图(铁路一张,公路一张),求1和n不直接相连的那张图的最短时间

#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
using namespace std;
const int INF=0x3f3f3f3f;
int G1[505][505];
int G2[505][505];
bool vis[505];
int lowcost[505];
int n,m;
void Dijkstra(int G[][505]){
	for(int i=1;i<=n;i++){
		lowcost[i]=INF;
		vis[i]=false;
	}
	lowcost[1]=0;
	for(int i=1;i<=n;i++){
		int k=-1;
		int min=INF;
		for(int j=1;j<=n;j++){
			if(!vis[j]&&lowcost[j]<min){
				min=lowcost[j];
				k=j;
			}
		}
		if(k==-1) break;
		vis[k]=true;
		for(int j=1;j<=n;j++){
			if(G[k][j]!=0&&!vis[j]&&lowcost[k]+G[k][j]<lowcost[j]){
				lowcost[j]=lowcost[k]+G[k][j];
			}
		}
	}
}

int main(){
	
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++){
		int a,b;
		scanf("%d%d",&a,&b);
		G1[a][b]=G1[b][a]=1;
	}
	if(G1[1][n]==0) {
		Dijkstra(G1);
		int ans=lowcost[n];
		if(ans==INF) printf("-1");
		else printf("%d\n",ans);
	}
	else{
		for(int i=1;i<=n;i++){
			for(int j=i+1;j<=n;j++){
				if(G1[i][j]==0) 
				G2[i][j]=G2[j][i]=1;
			}
		}
		Dijkstra(G2);
		int ans=lowcost[n];
		if(ans==INF) printf("-1");
		else printf("%d\n",ans);
	}
	return 0;
}