原题链接: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;
}