郭靖成为丐帮首领,他要去见丐帮的各位长老,但是长老们对他并不服气,所以,他们决定要给郭靖一个下马威。现在丐帮共有n名长老,他们每个人将扮演一个角色,要么是说谎者,要么是老实人。其中,
如果扮演说谎者,则他说的是假话。
如果扮演老实人,则他说的是真话。
长老之间知道每个人扮演的是什么角色。他们见到郭靖后,每个人向郭靖介绍其他长老,他们介绍的形式如下:
k r 1:表示k说r是老实人
k r 0:表示k说r是说谎者
这些介绍把郭靖弄糊涂了,他只好匆匆记下每个长老的话。现在请你帮助郭靖看看到底谁说的是真话,谁说的是假话。或者长老们自己也搞糊涂了吗,根本无法确定说是说谎者,谁是老实人。
输入格式:
第一行有一个整数L,表示共有L个测试组。(1≤L≤30)
其中每个测试组的第一行有两个整数n和m(1≤n≤105,1≤m≤105)。 随后的m行,每行有三个整数k,r,w(1≤k,r≤n,w={0,1})。
输出格式:
输出L行,每行为一个测试组结果。如果可以确定每个人的角色,则输出n个“0”和“1”构成的字符串,第i位为“0”表示第i位长老是说谎者,为“1”表示第i位长老是老实人。
如果根据测试组数据无法确定每位长老的角色,则输出“-1”。
输入样例:
在这里给出一组输入。例如:
2
5 4
1 2 1
2 3 0
2 4 0
1 5 0
3 3
1 2 1
1 3 0
2 3 1
输出样例:
在这里给出相应的输出。例如:
00111
-1
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int pre[N<<1],num[N<<1],vis[N<<1],ans[N];
int n,m;
int find(int x){
return x==pre[x]?pre[x]:pre[x]=find(pre[x]);
}
void merge(int x,int y)
{
int fx=find(x);
int fy=find(y);
if(fx!=fy)
{
pre[fx]=fy;
num[fy]+=num[fx];
}
}
void solve()
{
for(int i=1;i<=n;i++)
{
int fx=find(i);
int fy=find(i+n);
if(fx==fy)
{
printf("-1\n");
return ;
}
if(vis[fx]==0)
{
if(num[fx]>num[fy])
{
vis[fx]=1;
vis[fy]=-1;
}
else
{
vis[fx]=-1;
vis[fy]=1;
}
}
ans[i]=(vis[fx]==1);
}
for(int i=1;i<=n;i++)
printf("%d",ans[i]);
printf("\n");
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
for(int i=1;i<=2*n;i++)
{
pre[i]=i;
num[i]=(i<=n);
vis[i]=0;
}
for(int i=1;i<=m;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
if(w==1)
{
merge(u,v);
merge(u+n,v+n);
}
else
{
merge(u,v+n);
merge(u+n,v);
}
}
solve();
}
return 0;
}