B:Butterfly
總時間限制:
1000ms
單個測試點時間限制:
100ms
內存限制:
65536kB
描述
有一羣旅行愛好者,有一天,他們帶回了n只蝴蝶回來。他們相信每一隻都屬於兩個不同種類中的一種,爲了討論方便,我們稱它們爲A與B。他們想把n只標本分成兩組——一些屬於A且一些屬於B——但是直接標記任何一個標本對於他們是非常困難,因此他們決定採用下面的方法。
對每對標本i和j,他們細心地把它們放到一起研究。如果他們以自己的判斷足以確信,那麼他們把這對蝴蝶標記爲“相同”(這意味着他們相信這兩隻來自同一類)或者是“不同”(這意味着他們相信這兩隻來自不同的類)。他們也可以對某些標本判斷不出來而棄權,在這種情況下,我們稱這對標本是不明確的。
現在他們有n只標本的集合,還有對那些沒有棄權的標本對的m個判斷的集合(“相同”或者“不同”)。他們想知道這個數據與每隻蝴蝶來自A和B中的一個類的想法是否一致。更具體地說,如果對每對蝴蝶按照下述方式標記A或B是可能的,即對每個標爲“相同”的(i,j)對,就是i與j有相同標記的情況;對每個標爲“不同”的(i,j)對,就是i與j有不同標記的情況。那麼我們可以說這m個判斷是一致的。他們正在冥思苦想自己的判斷是否是一致的。請你幫他們設計合理的算法解決該問題。
輸入
輸入包含多組數據,以文件結束符爲終止。
每組數據第一行爲兩個整數,分別是n和m:
n爲蝴蝶的數量,編號從0到n-1
m爲關係的數量
接下來是m組關係數據,每組數據佔一行,爲三個整數,前兩個整數表示蝴蝶的編號,第三個整數爲關係的種類(相同或者不同):
0爲相同,1爲不同
1 < n <= 1000
1 < m <= 100000
輸出
合理就輸出YES
不合理就輸出NO
樣例輸入
3 3 0 1 0 1 2 1 0 2 1 3 3 0 1 0 1 2 1 0 2 0
樣例輸出
YES NO
提示
注意輸出的大寫和回車
題解:
這個題的數據很水,用並查集只要判斷最後集合數量大於3輸出NO也可以ac,但是個人以爲這種方式不對,用並查集最後還是要染色,不如直接用BFS染色
#include<bits/stdc++.h>
using namespace std;
int main()
{
//freopen("in.txt","r",stdin);
int m,n;
while(scanf("%d %d",&n,&m)!=EOF)
{
bool f=true;
queue<int> q;
int color[n]={0};
int a[n][n]={0};
for(int i=0;i<m;i++)
{
int aa,b,c;
scanf("%d %d %d",&aa,&b,&c);
if(c==0)
c=1;
else
c=2;
a[aa][b]=c;
a[b][aa]=c;
}
for(int k=0;k<n;k++)
{
if(color[k])
continue;
color[k]=1;
q.push(k);
while(!q.empty())
{
int t=q.front();
q.pop();
for(int j=0;j<n;j++)
{
if(a[t][j]==1)// same set
{
if(color[j]==0-color[t])
{
cout<<"NO"<<endl;
f=false;
break;
}
else if(color[j]==0)
{
color[j]=color[t];
q.push(j);
}
}
else if(a[t][j]==2)//diff set
{
if(color[j]==color[t])
{
cout<<"NO"<<endl;
f=false;
break;
}
else if(color[j]==0)
{
color[j]=0-color[t];
q.push(j);
}
}
}
if(!f)
break;
}
if(!f)
break;
}
if(f)
cout<<"YES"<<endl;
}
}