题意:小偷在有n个转角,m条无向边的小镇上从s点开始逃跑,请问有没有一个时间点小偷可能出现在n个转角中的任意一个,如果有输出YES。
分析:分析某个转角A,如果在一个时间点k被经过,那么小偷在K+1的时间点就不会在A点停留。由于为无向图,所以在k时间上从A到B,再在k+1时间上从B到A总是成立的,所以由此可知,A可能被经过的时间点是1和3,奇偶数规律一定,用vis[MAX][2]可以记录所有的经过情况。
#include<bits/stdc++.h>
using namespace std;
#define MAX 100005
vector<int> a[MAX];
int n,m,s;
bool vis[MAX][2]={};
struct PP{
int p;
int step;
};
int fun(){
PP now,nex;
now.p=s;
now.step=0;
vis[s][0]=true;
queue<PP> dq;
dq.push(now);
while(!dq.empty()){
now=dq.front();
dq.pop();
for(int i=0;i<a[now.p].size();i++){
nex.p=a[now.p][i];
nex.step=now.step+1;
if(!vis[nex.p][nex.step%2]){
vis[nex.p][nex.step%2]=true;
dq.push(nex);
}
}
}
int cnt1=0;
int cnt2=0;
for(int i=0;i<=n-1;i++){
if(vis[i][0]){
cnt1++;
}
if(vis[i][1]){
cnt2++;
}
}
if(cnt1==n||cnt2==n)
return 1;
else
return 0;
}
int main(){
int T,_;
scanf("%d",&T);
int l,r;
for(int _=1;_<=T;_++){
memset(vis,false,sizeof(vis));
for(int i=0;i<=n;i++){
a[i].clear();
}
scanf("%d%d%d",&n,&m,&s);
for(int i=1;i<=m;i++){
scanf("%d%d",&l,&r);
a[l].push_back(r);
a[r].push_back(l);
}
printf("Case %d: ",_);
if(fun())
printf("YES\n");
else
printf("NO\n");
}
return 0;
}