CodeForces 1702E Split Into Two Sets(并查集)

原题链接https://codeforces.com/contest/1702/problem/E

题意:给你 n个数对。数对中的每个数字都是从 1 到 n 的。现在问是否能将这些数对分到两个集合中。使得每个集合中没有任何一个重复的数字。

例如有下面这四个数对:{1,4},{1,3},{3,2},{4,2}。

正确地分配这些数对:第一个集合包含数对 {1,4} 和 {3,2}。第二个包含 {1,3} 和 {4,2}。

思路: 其实完全可以不用想怎么分组,用并查集将每一个数对{x,y}中的x,y放在一个连通块中,那么不成立的情况就分为:1.数对{x,y}中存在x==y,2.如果某一个数出现两次以上,3.连通块中的个数是奇数。有以上任意一种情况就输出NO。(当然前提都是数对全部输入完毕)

AC代码:

#include <bits/stdc++.h>
const int N = 1e6 + 9;

int p[N],cnt[N];

int find(int x){
	if(p[x]!=x) p[x]=find(p[x]);
	return p[x];
}

void solve() {
	int n;
	std::cin >> n;
	for(int i=1;i<=n;i++) {
		p[i]=i;
		cnt[i]=1;
	}	
	std::map<int,int>q;
	int flag=0;
	for(int i=1;i<=n;i++){
		int x,y;
		std::cin>>x>>y;
		q[x]++,q[y]++;
		if(x==y) flag=1;

		int a=find(x),b=find(y);
		if(a!=b){
			p[a]=b;
			cnt[b]+=cnt[a];
		}
	}

	for(int i=1;i<=n;i++){
		if(flag || cnt[find(i)]&1 || q[i]>2){
			std::cout<<"NO\n";
			return ;
		}
	}
	std::cout<<"YES\n";
	q.clear();
}

int main() {
    std::ios_base::sync_with_stdio(false);
    std::cin.tie(nullptr);
    
    int T;
    std::cin >> T;
    
    while (T--) {
        solve();
    }
    
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值