zoukankan      html  css  js  c++  java
  • 牛客 边的染色(思维+dfs)

    这题转化太巧妙,将边权转化成点权,根据性质,在一个环内,每个点都会影响两条边,也就是说,将两点之间的边权设置为两个点权的异或值,那么答案肯定为0.因为每个点都异或两次

    这样的话,假如没有设计过某些边权,那么答案就是所有点的取值/2,因为当所有0变成1所有1变成0,那么边权是一毛一样的。

    考虑有某些边权是存在的,那么我们就要把这些边权所组成的连通块找出来,在某一个全部由存在边权的连通块中,一个点确定,所有点确定,因此可变的只有这个点,答案就要除以2的k-1次,k是连通块中点的个数,这符合除法定理。另外还要判断矛盾,也就是一开始的图就不符合答案。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=1e6+10;
    const ll mod=998244353;
    int h[N],ne[N],e[N],w[N],idx;
    int c[N];
    int n,m;
    int sum;
    void add(int a,int b,int c){
        e[idx]=b,ne[idx]=h[a],w[idx]=c,h[a]=idx++;
    }
    int dfs0(int u,int x){
        c[u]=x;
        int i;
        for(i=h[u];i!=-1;i=ne[i]){
            int j=e[i];
            if(w[i]==-1)
                continue;
            if(c[j]!=-1&&(x^w[i])!=c[j])
                return 0;
            if(c[j]==-1&&!dfs0(j,x^w[i]))
                return 0;
        }
        return 1;
    }
    void dfs1(int u,int fa){
        c[u]=1;
        sum++;
        for(int i=h[u];i!=-1;i=ne[i]){
            int j=e[i];
            if(j==fa)
                continue;
            if(c[j]==-1){
                dfs1(j,u);
            }
        }
    }
    void dfs2(int u,int fa){
        c[u]=1;
        int i;
        sum--;
        for(i=h[u];i!=-1;i=ne[i]){
            int j=e[i];
            if(j==fa)
                continue;
            if(w[i]!=-1){
                if(!c[j])
                dfs2(j,u);
            }
        }
    }
    int main(){
        int i;
        cin>>n>>m;
        memset(c,-1,sizeof c);
        memset(h,-1,sizeof h);
        for(i=1;i<=m;i++){
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            add(a,b,c);
            add(b,a,c);
        }
        int flag=0;
        for(i=1;i<=n;i++){
            if(c[i]==-1){
                if(!dfs0(i,1)){
                    cout<<0<<endl;
                    return 0;
                }
            }
        }
        memset(c,-1,sizeof c);
        for(i=1;i<=n;i++){
            if(c[i]==-1){
                dfs1(i,-1);
                sum-=1;
            }
        }
        memset(c,0,sizeof c);
        for(i=1;i<=n;i++){
            if(!c[i]){
                dfs2(i,-1);
                sum+=1;
            }
        }
        ll k=1;
        for(i=1;i<=sum;i++){
            k=(k*2)%mod;
        }
        cout<<k<<endl;
    }
    View Code
  • 相关阅读:
    Python正则表达式re模块
    time,datetime,calendar模块
    Python的特殊属性和魔法函数
    Django环境搭建
    第十二篇 os模块
    第十一篇 logging模块
    Page Object设计模式
    实现自动发邮件功能
    cs61a Mutable Data 2 学习笔记和补充
    Lambda Expressions and Higher-Order Functions 学习笔记和习题解答
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/12989012.html
Copyright © 2011-2022 走看看