2017年上海金马五校程序设计竞赛(网上资格赛)Problem B : Coach

Description

In the ACM training team, the coach wants to split all students into many groups and each group consists of three students. Let's assume that all students are numbered from  1 1 to  n n. The teacher wants the groups to achieve good results, so he wants to hold the following condition: In a group of three students, they are friends. Also it is obvious that each student must be in exactly one team. If  A A and  B B are friends,  B B and  C C are friends, then  A A and  C C are friends.

 

Input

There are multiple test cases.

For each test case, the first line contains integers  n n and  m m  (1n5000,0m5000) (1≤n≤5000,0≤m≤5000). Then follows  m m lines, each contains a pair of integers  ai,bi ai,bi  (1ai,bin) (1≤ai,bi≤n). The pair  ai,bi ai,bi means that the students  ai ai and  bi bi are friend. It is guaranteed that each pair of  ai ai and  bi bi occurs in the input at most once.

 

Output

If the required group division plan doesn't exist, print “No”. Otherwise, print “Yes”.

 

Sample Input

3 0
6 4
1 2
2 3
4 5
5 6

 

Sample Output

No
Yes


这个题吧,就是并查集,我原先是去查每一个人所在的那可树上是不是都等于3,就yes,但是我后来发现了问题,如果六个人都是朋友的话那也可以3 3分配,所以我把判断条件改成了3的整数倍


#include <iostream>
#include <map>
using namespace std;
map<int,int> p;
int par[100005],r[100005],num[100005];
void init(){
	for(int i=0;i<100005;i++){
		par[i]=i;
		num[i]=1;
	}
}
int findroot(int x){
	if(par[x]==x) return x;
	else return par[x]=findroot(par[x]);
}
void unite(int x,int y){
	x=findroot(x);
	y=findroot(y);
	if(x==y){
		return;
	}
	par[y]=x;
	num[x]+=num[y];
}
int main(){
	int n,m;
	while(scanf("%d%d",&n,&m)!=EOF){
		if(m == 0) {
			printf("No\n");
			continue;
		}
		p.clear();
		init();
		int k=1;
		for(int i=0;i<m;i++){
			int a,b;
			scanf("%d%d",&a,&b);
			if(p.find(a)==p.end()){
				p[a]=k++;
			}
			if(p.find(b)==p.end()){
				p[b]=k++;
			}
			unite(p[a],p[b]);
		}
		for(int i = 1;i<=n;i++){
			if(num[findroot(p[i])]%3!=0){
				printf("No\n");
				break;
			}
			if(i==n&&num[findroot(p[i])]%3==0){
				printf("Yes\n");
			}
		}
	}
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_我走路带风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值