【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<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<string>
#include<vector>
#include<unordered_map>
#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<pair<int,int>,int> mp;
int bfs(int st,int ed){
	for(int i=0;i<=500;i++) dis[i]=inf,vis[i]=0;
	queue<int> 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;i<m;i++){
		scanf("%d%d",&u,&v);
		if(u>v) 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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章