灰狼呼唤着同胞(brethren)

时间:2021-04-27 04:21:10

灰狼呼唤着同胞(brethren)

灰狼呼唤着同胞(brethren)

灰狼呼唤着同胞(brethren)

灰狼呼唤着同胞(brethren)

灰狼呼唤着同胞(brethren)

灰狼呼唤着同胞(brethren)

灰狼呼唤着同胞(brethren)

灰狼呼唤着同胞(brethren)

先求出确定边的联通块,有cnt块,显然方案数为2^(cnt-1)

联通块用dfs很好求

但此题还有并查集解法,且与一道叫团伙的题很像

边为0为敌人,1为朋友,敌人的敌人是朋友,朋友的朋友是朋友,正好对应本题情况

数据在管理里的文件

现附上dfs版(并查集还没写)

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct Node
{
int next,to,dis;
}edge[];
int head[],num,col[],n,m,cnt;
long long ans;
bool ok;
void add(int u,int v,int d)
{
num++;
edge[num].next=head[u];
head[u]=num;
edge[num].to=v;
edge[num].dis=d;
}
void dfs(int x)
{int i,j;
for (i=head[x];i;i=edge[i].next)
{
int v=edge[i].to;
if (col[v]==-)
{
if (edge[i].dis==) col[v]=col[x]^,dfs(v);
else col[v]=col[x],dfs(v);
}
else
{
if (edge[i].dis==&&col[v]==col[x]) ok=;
if (edge[i].dis&&col[v]!=col[x]) ok=;
}
}
}
int main()
{int Test,T,i,u,v,d;
cin>>Test>>T;
while (T--)
{num=;cnt=;
memset(head,,sizeof(head));
scanf("%d%d",&n,&m);
for (i=;i<=m;i++)
{
scanf("%d%d%d",&u,&v,&d);
add(u,v,d);
add(v,u,d);
}
for (i=;i<=n;i++) col[i]=-;
ok=;
for (i=;i<=n;i++)
if (col[i]==-)
{
cnt++;
col[i]=;
dfs(i);
}
ans=;
if (!ok) printf("0\n");
else
{
for (i=;i<=cnt-;i++)
ans=(ans*)%;
printf("%lld\n",ans);
}
}
}