1. 程式人生 > 實用技巧 >Educational Codeforces Round 56 (Rated for Div. 2) D. Beautiful Graph (二分圖染色)

Educational Codeforces Round 56 (Rated for Div. 2) D. Beautiful Graph (二分圖染色)

  • 題意:有\(n\)個點,\(m\)條邊的無向圖,可以給每個點賦點權\({1,2,3}\),使得每個點連的奇偶不同,問有多少種方案,答案對\(998244353\)取模.

  • 題解:要使得每個點所連的奇偶不同,很明顯是二分圖染色,那麼對於某一個聯通塊,我們可以對左邊的點賦\(2\),右邊的點賦\({1,3}\),那麼左邊的點沒有選擇,只有一種情況,而右邊的點每個點可以有兩種情況,如果右邊的點數是\(k2\),那麼方案數就是\(2^k2\),如果左邊賦\({1,3}\)且點數為\(k1\),右邊賦\(2\),方案數就是\(2^k1\),所以一個聯通塊的方案數就是\(2^k1+2^k2\).我們可以不考慮點權,直接dfs二分圖染色,記錄二分圖兩邊的點數,再直接貢獻給答案即可.

  • 程式碼:

    int t;
    int n,m;
    vector<int> v[N];
    int color[N];
    int g[N];
    int cnt[N];
    int ans;
    
    bool dfs(int x,int c){
        color[x]=c;
    
        for(auto w:v[x]){
            if(!color[w]){
                if(!dfs(w,3-c)) return false;
            }
            else{
                if(color[w]==c) return false;
            }
        }
        cnt[c]++;
        return true;
    }
    
    int main() {
        //ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
        scanf("%d",&t);
        g[0]=1;
    
        for(int i=1;i<=300010;++i){
            g[i]=g[i-1]*2%mod;
        }
       
        while(t--){
            scanf("%d %d",&n,&m);
    
            ans=1;
    
            for(int i=1;i<=n;++i){
                color[i]=0;
            }
    
            for(int i=1;i<=m;++i){
                int a,b;
                scanf("%d %d",&a,&b);
                v[a].pb(b);
                v[b].pb(a);
            }
    
            bool ok=true;
    
            for(int i=1;i<=n;++i){
                if(!color[i]){
                    cnt[1]=cnt[2]=0;
                    if(!dfs(i,1)){
                        ok=false;
                        break;
                    }
                    else{
                        ans=(ll)ans*(g[cnt[1]]+g[cnt[2]])%mod;
                    }
                }
            }
    
            if(ok) printf("%d\n",ans);
            else printf("0\n");
    
            for(int i=1;i<=n;++i) v[i].clear();
    
        }
    
    
        return 0;
    }