CF553C Love Triangles(二分图)

Tyher推的好题.
题意就是给你一些好边一些坏边,其他边随意,让你求符合好坏坏~,或者只包含好好好的三元环的无向图个数.
坏坏的Tyher的题意是这样的.
再翻译得更加透彻一点就是:给你一些0(好边)边和1(坏边)边,让你求只包含011或者000的三元环的图的个数.
强强的zsy说:"Tyher你好坏啊!这不就是求合法的二分图个数嘛."
容易发现满足题目条件的图一定是只含有偶环(这里是边权和为偶数)的图,那不就是二分图嘛,于是只要统计一下1边相连的联通块个数k,答案就是\(2^{k-1}\)(因为二分图的两个集合是无区别的两个集合,所以除以2)

#include<bits/stdc++.h>
#define mod 1000000007
#define maxn 100005
#define ll long long
using namespace std;
int n,m,vis[maxn],ans,cor[maxn];
int head[maxn],nxt[maxn<<1],to[maxn<<1],w[maxn<<1],cnt;
void add(int u,int v,int ww)
{
	nxt[++cnt]=head[u];head[u]=cnt;
	to[cnt]=v;w[cnt]=ww;
}
int ksm(int a,int b)
{
	int res=1;
	while(b)
	{
		if(b&1)res=(ll)res*a%mod;
		b>>=1;a=(ll)a*a%mod;
	}
	return res;
}
void dfs(int u,int ff,int ty)
{
	if(vis[u])
	{
		if(cor[u]!=ty)cout<<"0"<<endl,exit(0);
		return ;
	}
	vis[u]=1;cor[u]=ty;
	for(int i=head[u];i;i=nxt[i])
	{
		int v=to[i];if(v==ff)continue;
		dfs(v,u,(w[i]?ty:-ty));
	}
}
int main()
{
	cin>>n>>m;
	for(int i=1,u,v,ww;i<=m;i++)
		scanf("%d%d%d",&u,&v,&ww),add(u,v,ww),add(v,u,ww);
	for(int i=1;i<=n;i++)if(!vis[i])ans++,dfs(i,0,1);
	printf("%d\n",ksm(2,ans-1));
	return 0;
}

posted @ 2018-10-30 20:11  Brioche  阅读(553)  评论(2编辑  收藏  举报