CF553C Love Triangles

发布时间 2023-10-16 18:31:06作者: 空気力学の詩

很有意思的一个题,想了一会才发现解题的关键

首先我们注意到对于某个大小\(\ge 3\)的连通块,其实连通块内的所有边的颜色都会被已知的边唯一确定

而不同的连通块间的连边方式有两种,因此设连通块个数为\(tot\),最后的答案就是\(2^{tot-1}\)

但还要考虑判掉不合法的情况,注意到不管是\(111\)还是\(100\),从某个点沿着环走回这个点经过的\(1\)边数量都是奇数

那么很容易想到用染色来判断合法性,具体地,我们把\(1\)对应的边看作连接了两个颜色相同的点;\(0\)对应的边连接了两个颜色不同的点,然后看这个图是否可以黑白染色即可

#include<cstdio>
#include<iostream>
#include<utility>
#include<vector>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<set>
#include<array>
#include<random>
#include<bitset>
#include<ctime>
#include<limits.h>
#include<assert.h>
#include<unordered_set>
#include<unordered_map>
#define RI register int
#define CI const int&
#define mp make_pair
#define fi first
#define se second
#define Tp template <typename T>
using namespace std;
typedef long long LL;
typedef long double LDB;
typedef unsigned long long u64;
typedef __int128 i128;
typedef pair <int,int> pi;
typedef vector <int> VI;
typedef array <int,3> tri;
const int N=100005,mod=1e9+7;
int n,m,x,y,z,tot,col[N]; vector <pi> v[N];
inline void DFS(CI now)
{
	for (auto [to,w]:v[now])
	if (!~col[to]) col[to]=col[now]^w,DFS(to); else
	if (col[to]!=(col[now]^w)) { puts("0"); exit(0); }
}
int main()
{
	//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
	RI i; for (scanf("%d%d",&n,&m),i=1;i<=m;++i)
	scanf("%d%d%d",&x,&y,&z),z^=1,v[x].push_back(pi(y,z)),v[y].push_back(pi(x,z));
	for (memset(col,-1,sizeof(col)),i=1;i<=n;++i)
	if (!~col[i]) col[i]=0,DFS(i),++tot;
	int ans=1; for (i=1;i<tot;++i) ans=2LL*ans%mod;
	return printf("%d",ans),0;
}