Description
已知有 n 个学生,其中有男生也有女生,给定 m 个关系,每个关系表示两个同学性别是否相同。如 同学A 和同学 B 是同性,或不是同性,判断这些条件中是否存在矛盾。
Input
第一行为两个整数 n(1 <= n <= 1000), m(1 <= m <= 1000),每个同学编号为1到n,之后m行,每行三个整数,前两个整数表示两个同学的编号,第三个整数为0或者1,若为0,则表示两个同学为同性,否则为异性。
Output
一行,若存在矛盾,输出YES,否则输出NO
Sample Input
5 5 1 2 1 2 3 1 3 4 1 4 5 1 5 1 0Sample Output
NO
思路
种类并查集
数据分为两类:女生、男生,对于同学a,我们可以假设一个a的对立异性为a+n以方便判断真假;
例:输入a b 1,a和b为异性,我们将a与b+n进行合并,b与a+n进行合并,这样的话判断真假只需要判断a是否等于b+a或b是否等于a+n
ac代码如下
#include<bits/stdc++.h>
using namespace std;
int x[2005];//两种阵营开两倍大的数组
int high[2005]={0};//优化并查集的长度
void chushi(){
for(int i=0;i<2005;i++){
x[i]=i;
}
}
int find(int a){
return x[a]==a?x[a]:x[a]=find(x[a]);
}
void hebing(int a,int b){
int f1=find(a);
int f2=find(b);
if(f1==f2)
return;
else{
if(high[f1]<high[f2])
x[f1]=f2;
else{
x[f2]=f1;
if(high[f1]==high[f2])
high[f1]++;
}
}
}
int main(){
int n,m;
chushi();
cin>>n>>m;
int j,k,l;
int flag=0;//标记
for(int i=0;i<m;i++){
cin>>j>>k>>l;
if(l==1){
if(x[j]==x[k]){
flag=1;
}
else{
hebing(j,k+n);
hebing(k,j+n);
}
}
else{
if(x[j+n]==x[k]||x[j]==x[k+n])//对是否合理进行判断
{
flag=1;
}
else{
hebing(j,k);
hebing(j+n,k+n);
}
}
}
if(flag)
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
return 0;
}