题意:
给你一幅图,给你一个起点,然后问你存不存在一个时刻,所有点可以在那个时刻到达。
思路:
这幅图首先是联通的;
如果出现奇数环,则满足在某一时刻都可能到达;
然后判断奇数环用二分图性质搞也是神奇...
#include<bits/stdc++.h>
using namespace std;
#include<bits/stdc++.h>
using namespace std;
/*
题意:
使某一时刻到达该图任意顶点:
1.图是联通的,
2.无向图的每一个顶点必须保证能够在奇时刻或偶时刻可以进行访问.
(二部图的顶点两个顶点集合只能在奇或偶时刻对齐进行访问)
*/
const int N=1e5+10;
struct asd{
int to;
int next;
};
asd q[N*10];
int head[N*10],tol;
int n,m,s;
int col[N];
int pre[N];
void init()
{
tol=0;
memset(head,-1,sizeof(head));
for(int i=0;i<n;i++)
pre[i]=i;
}
void add(int u,int v)
{
q[tol].to=v;
q[tol].next=head[u];
head[u]=tol++;
}
int Find(int x)
{
int r=x;
while(pre[r]!=r)
r=pre[r];
int i=x,j;
while(pre[i]!=r)
{
j=pre[i];
pre[i]=r;
i=j;
}
return r;
}
void Merge(int a,int b)
{
int aa=Find(a);
int bb=Find(b);
if(aa!=bb)
pre[aa]=bb;
}
bool Judge(int s)
{
queue<int>que;
col[s]=0;
que.push(s);
while(!que.empty())
{
int u=que.front();que.pop();
for(int i=head[u];i!=-1;i=q[i].next)
{
int v=q[i].to;
if(col[v]==-1)
{
col[v]=1-col[u];
que.push(v);
}
else
if(col[v]==col[u])
return false;
}
}
return true;
}
int main()
{
int T,cas=1;
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d",&n,&m,&s);
init();
int u,v;
while(m--)
{
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
Merge(u,v);
}
printf("Case %d: ",cas++);
int flag=0;
for(int i=0;i<n;i++)
if(pre[i]==i)
flag++;
if(flag!=1)
{
puts("NO");
continue;
}
memset(col,-1,sizeof(col));
if(Judge(s))
puts("NO");
else
puts("YES");
}
return 0;
}