Uva11396 爪分解(二分图判定)

来源:互联网 发布:sql数据库2000 编辑:程序博客网 时间:2024/06/09 19:09

【问题描述】  
  给出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

一个爪就相当于把点分成中心和附属2类,不能跟换,因为每条边只能用1次。所有直接判断这个图是否是二分图就可以了。


#include<iostream>

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
using namespace std;
const int maxn=1005;
int n,m,T,ok;
vector<int>a[maxn];
bool vis[maxn],c[maxn];


void init()
{
memset(vis,0,sizeof(vis));
memset(c,0,sizeof(c));
for(int i=1;i<=n;i++)
a[i].clear();
int x,y;
scanf("%d%d",&x,&y);
while(x!=0&&y!=0)
{
a[x].push_back(y);
a[y].push_back(x);
scanf("%d%d",&x,&y);
}
}


void bfs(int p)
{
queue<int>q;
q.push(p);
c[p]=1;
while(!q.empty())
{
int t=q.front();
q.pop();
for(int i=0;i<a[t].size();i++)
{
int j=a[t][i];
if(vis[j]&&c[j]==c[t]) ok=0;
if(vis[j]==0) 
{
q.push(j);
c[j]=1-c[t];
vis[j]=1;
}
}
if(ok==0) break;
}
}
int main()
{
while(scanf("%d",&n)==1)
{
 init();
 ok=1;
 for(int i=1;i<=n;i++) if(vis[i]==0)
 bfs(i);
 if(ok) printf("YES\n");
 if(ok==0) printf("NO\n");
    }
    return 0;
}
1 0
原创粉丝点击