【问题描述】
给出n(n≤300)个节点的简单无向图(无自环无重边),每个点的度为3。现在你需要判断能否将它分解成若干个爪(如图所示)。在你的方案中,每条边必须恰好属于一个爪,但同一个节点可以出现在多个爪里。
【输入格式】
多组输入数据:
每组数据第一行为这个图的点数n,第二行开始每行2个整数a, b(1 <= a, b <= n)为该图的边,以”0 0”结束。
【输出格式】
对于每组数据,如果能分解则输出”YES”否则输出”NO”
【输入样例】
4
1 2
1 3
1 4
2 3
2 4
3 4
0 0
6
1 2
1 3
1 6
2 3
2 5
3 4
4 5
4 6
5 6
0 0
【输出样例】
NO
NO
【数据范围】
n≤300
简单的二分图判断
#include<cstdlib>
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<vector>
#include<cstring>
#include<queue>
#define maxn 1005
using namespace std;
int T,n,m,x,y,d,ok;
vector<int>g[maxn];
int vis[maxn]={0};
void fuck(int t)
{
queue<int>q;
q.push(t);
vis[t]=1;
while(!q.empty())
{
int qq=q.front();
q.pop();
for(int i=0;i<g[qq].size();i++)
{
int j=g[qq][i];
if(vis[qq]==vis[j]) ok=0;
if(vis[j]==0)
{
q.push(j);
vis[j]=3-vis[qq];
}
if(ok==0) break;
}
if(ok==0) break;
}
}
int main()
{
freopen("in.txt","r",stdin);
while(scanf("%d",&n)==1)
{
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++)
g[i].clear();
scanf("%d%d",&x,&y);
while(x!=0&&y!=0)
{
g[x].push_back(y);
g[y].push_back(x);
scanf("%d%d",&x,&y);
}
ok=1;
for(int i=1;i<=n;i++) if(vis[i]==0)
fuck(i);
if(ok) printf("YES\n");
else printf("NO\n");
}
return 0;
}