给你一个图,每个节点可以赋值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;
}