链接:csu 1356
///方法1 并查集
#include<iostream>
#include<cstdio>
using namespace std;
#define MAX 1000100
int sum[MAX];
int down[MAX];
int father[MAX];
int rank[MAX];
int add;
void makeset()
{
int i;
for(i=0; i<MAX; i++)
{
sum[i]=1;
down[i]=0;
father[i]=i;
}
}
int find(int num)
{
int t;
if(father[num]!=num)
{
t=find(father[num]);
if(t!=father[num])
{
down[num]=add%2;
}
add=(down[num]+1)%2;
father[num]=t;
return t;
}
return num;
}
void Union(int x,int y)
{
int t=find(x);
int s=find(y);
if(t==s) return ;
if(sum[t]>=sum[s])
{
father[y]=x;
down[y]=(down[x]+1)%2;
sum[x]+=sum[y];
}
else
{
father[x]=y;
down[x]=(down[y]+1)%2;
sum[y]+=sum[x];
}
}
int main()
{
int t,n,m,a,b,i;
scanf("%d",&t);
int u=0;
while(t--)
{
u++;
int s;
makeset();
scanf("%d %d %d",&n,&m,&s);
bool flag=1;
for(i=0; i<m; i++)
{
scanf("%d %d",&a,&b);
Union(a,b);
int p,q;
p=find(a);
q=find(b);
if(down[a]==down[b]) flag=0;///表示奇圈
}
int fa = find(0);
for(int i = 0; i < n; i ++)
{
if(find(i) != fa) flag = true;
}
if(!flag)
{
printf("Case %d: YES\n", u);
}
else printf("Case %d: NO\n", u);
}
return 0;
}
///方法二 黑白染色(前提是连通的图)
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cmath>
#include<map>
#include<set>
#define maxn 100100
#define CLR(a, b) memset(a, b, sizeof(a))
using namespace std;
#ifdef __LL64
typedef __LL64 LL;
#else
typedef long long LL;
#endif
int color[maxn];
vector<int> G[maxn];
bool bipartite(int u)
{
for(int i = 0; i < G[u].size(); i ++)
{
int v = G[u][i];
if(color[u] == color[v]) return false;
if(!color[v])
{
color[v] = 3 - color[u];
if(!bipartite(v)) return false;
}
}
return true;
}
int main()
{
int T, cas = 1, n, m, s;
scanf("%d", &T);
while(T --)
{
scanf("%d%d%d", &n, &m, &s);
for(int i = 0; i < n; i ++) G[i].clear();
for(int i = 0; i < m; i ++)
{
int u, v;
scanf("%d%d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
}
CLR(color, 0);
color[s] = 1;
if(!bipartite(s))
printf("Case %d: YES\n", cas ++);
else printf("Case %d: NO\n", cas ++);
}
}