【CodeForces - 602C】The Two Routes(思维)

题意:

有一张n个点的图,任意两个点之间都有一条虚边或实边。现在有两个小朋友想从点1走到点n,一个小朋友只能走虚边,一个小朋友只能走实边。现在问这两个小朋友都走到终点最少需要多少时间。如果没有合法方案输出-1。

Input

第一行包含两个整数 n 和 m (2 ≤ n ≤ 400, 0 ≤ m ≤ n(n - 1) / 2) — 表示点数和实边的数量。

之后 m 行包含两个整数 u 和 v,表示一条连接 u 和 v 的实边。 (1 ≤ u, v ≤ nu ≠ v)

保证任意两点之间最多有一条实边。

Output

输出一个整数 — 最少需要的时间。

思路:

即对给出的图和其补图求起点到终点的最短路,两者取最大值。特殊的是其中一个图一定会包含1-n这条边,因此这个图的最短路就是1,只用跑另一个就可以。

ac代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define mod (1000000007)
using namespace std;
typedef long long ll;
const int maxn=2e5+100;
const int inf=0x3f3f3f3f;
struct node{
	int v,nxt;
}side[maxn];
int head[1000],cnt=0,dis[1000],vis[1000];
void add(int x,int y){
	side[cnt].v=y;
	side[cnt].nxt=head[x];
	head[x]=cnt++;
}
map,int> mp;
int bfs(int st,int ed){
	for(int i=0;i<=500;i++) dis[i]=inf,vis[i]=0;
	queue q;
	dis[st]=0;
	q.push(st);
	while(!q.empty()){
		int nn=q.front();
		q.pop();
		if(vis[nn]) continue;
		if(nn==ed) break;
		vis[nn]=1;
		for(int i=head[nn];i!=-1;i=side[i].nxt){
			int ty=side[i].v;
			if(dis[ty]>dis[nn]+1){
				dis[ty]=dis[nn]+1;
				q.push(ty);
			}
		}
	}
	return dis[ed]==inf?-1:dis[ed];
}
int main(){
	int n,m,u,v,ff=0;
	scanf("%d%d",&n,&m);
	for(int i=0;i<=n;i++) head[i]=-1;
	for(int i=0;iv) swap(u,v);
		if(u==1&&v==n) ff=1;
		mp[make_pair(u,v)]=1;
		add(u,v);
		add(v,u);
	}
	if(ff){
		cnt=0;
		for(int i=0;i<=n;i++) head[i]=-1;
		for(int i=1;i<=n;i++)
			for(int j=i+1;j<=n;j++)
				if(!mp[make_pair(i,j)]){
					add(i,j);add(j,i);
				}
	}
	printf("%d\n",bfs(1,n));
	return 0;
}

 

你可能感兴趣的:(【CodeForces - 602C】The Two Routes(思维))