Beautiful Graph CodeForces - 1093D 二分圖判定 簡單組合
阿新 • • 發佈:2020-11-23
Beautiful Graph CodeForces - 1093D 二分圖判定 簡單組合
題意
給定一張\(n\)個點\(m\)條邊的無向圖,可以給每個點賦值\(1,2,3\)。
要求賦值以後每條邊的兩個端點權值和是奇數,問有多少種賦值方法,答案對\(998244353\)取模
\[1\leq t \leq 3 \times 10^5\\ 1\leq n \leq 3 \times 10^5,0\leq m\leq3 \times 10^5 \]分析
顯然只有2不能和1或3組合才可以,於是可以發現把原圖抽象成2分圖,然後對兩個分部統計個數即可。
不同的連通塊可以通過乘法原理算答案。每個連通塊內一部可以填1也可以填3,也可以左邊2或者右邊2
於是每一塊的答案就是\(2^p + 2^q\)
如果連通塊不是二分圖,那麼無法做到
程式碼
vector<int> e[maxn]; ll pow2[maxn]; int col[maxn]; int c1,c2; bool flag; void dfs(int u,int co){ col[u] = co; if(!co) c1++; else c2++; for(auto v:e[u]){ if(col[v] < 0) dfs(v,co ^ 1); else if(col[v] == co){ flag = false; return; } } } void solve(){ int n = readint(); int m = readint(); flag = true; for(int i = 0;i <= n;i++) e[i].clear(),col[i] = -1; for(int i = 0;i < m;i++){ int x = readint(); int y = readint(); e[x].pb(y); e[y].pb(x); } ll ans = 1; for(int i = 1;i <= n;i++){ if(col[i] == -1){ c1 = c2 = 0; dfs(i,0); if(!flag) { ans = 0; break; } ans *= pow2[c1] + pow2[c2]; ans %= MOD; } } cout << ans << '\n'; } int main(){ int T = readint(); pow2[0] = 1ll; for(int i = 1;i < maxn;i++) pow2[i] = (pow2[i - 1] << 1) % MOD; while(T--){ solve(); } }