Codeforces 1093D. Beautiful Graph

给你一个图,每个节点可以赋值1,2,3三种数字,相邻的节点的和必须是奇数,问有多少中方法。
参考
原来是二分染色,原来的想法是只要图中有环就不行,想法错误,因为如果一条回路节点的个数是偶数的话也是能染的,
最后,不要盲目相信memset!10^6用memset照样TLE

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL mod = 998244353 ;
int t,n,m,u,v,f,cnt1,cnt2,vis[303030],muti[303030];
LL ans;
vector<int> mp[303030];
void dfs(int u){
	if(vis[u] == 1) cnt1++;
	else cnt2++;
	for(register int i  = 0;i<mp[u].size();++i){ 
		int v = mp[u][i];
		if(vis[v] == vis[u]) {
			f = 1;return ;
		}
		else if(!vis[v])	{
			if(vis[u] == 1) vis[v] = 2;
			else if(vis[u] == 2) vis[v] = 1;
			dfs(v);
		}
	} 
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);

	muti[0] = 1;
	for(int i = 1;i<303030;i++)
		muti[i] = muti[i-1]*2%mod;
	cin>>t;
	while(t--){
		cin>>n>>m;f=0;ans = 1;
		for(register int i = 1;i<=n;++i) mp[i].clear(),vis[i] = 0;		
		for(register int i = 0;i<m;++i){
			cin>>u>>v;
			mp[u].push_back(v);
			mp[v].push_back(u);
		}
		for(register int i = 1;i<=n;++i)	{
			cnt1 = cnt2 = 0;
			if(	!vis[i]) {
				vis[i] = 1; 
				dfs(i);
				if(f) { 
					ans = 0;break;
				}
				else{ 
					ans *=LL(muti[cnt1] + muti[cnt2]);
					ans %= mod;
				} 
			}
		}; 
		cout<<ans<<endl;
	} 
	return 0; 
} 

猜你喜欢

转载自blog.csdn.net/winhcc/article/details/85041822
今日推荐