zoukankan      html  css  js  c++  java
  • 灰狼呼唤着同胞(brethren)

    灰狼呼唤着同胞(brethren)

    先求出确定边的联通块,有cnt块,显然方案数为2^(cnt-1)

    联通块用dfs很好求

    但此题还有并查集解法,且与一道叫团伙的题很像

    边为0为敌人,1为朋友,敌人的敌人是朋友,朋友的朋友是朋友,正好对应本题情况

    数据在管理里的文件

    现附上dfs版(并查集还没写)

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #include<algorithm>
    #define mod (998244353)
    using namespace std;
    void read(int &x)
    {
        x=0;int f=1;char i=getchar();
        while(i<'0'||i>'9'){if(i=='-')f=-1;i=getchar();}
        while(i>='0'&&i<='9'){x=x*10+i-'0';i=getchar();}
        x*=f;
    }
    int t,n,m;
    struct node
    {
        int next,to,dis;
    }edge[2000005];
    int size,head[100005],color[100005],cnt;
    void putin(int from,int to,int dis)
    {
        size++;
        edge[size].to=to;
        edge[size].dis=dis;
        edge[size].next=head[from];
        head[from]=size;
    }
    bool dfs(int r)
    {
        int i;
        bool ans=1;
        for(i=head[r];i!=-1;i=edge[i].next)
        {
            int y=edge[i].to;
            if(color[y]==-1)
            {
                if(edge[i].dis==0)color[y]=color[r]^1;
                else color[y]=color[r];
                ans&=dfs(y);
            }
            else
            {
                if(edge[i].dis==0&&color[y]==color[r])return 0;
                if(edge[i].dis==1&&color[y]!=color[r])return 0;
            }
        }
        return ans;
    }
    int main()
    {
        freopen("brethren.in","r",stdin);
        freopen("brethren.out","w",stdout);
        int i,j;
        read(t);read(t);
        while(t--)
        {
            read(n);read(m);
            size=0;cnt=0;
            memset(head,-1,sizeof(head));
            for(i=1;i<=m;i++)
            {
                int from,to,dis;
                read(from);read(to);read(dis);
                putin(from,to,dis);
                putin(to,from,dis);
            }
            for(i=1;i<=n;i++)color[i]=-1;
            bool flag=1;
            for(i=1;i<=n;i++)
            {
                if(color[i]==-1)
                {
                    cnt++;
                    color[i]=1;
                    if(!dfs(i)){flag=0;break;}
                }
            }
            if(!flag)printf("0
    ");
            else
            {
                int ans=1;
                for(i=1;i<cnt;i++)
                {
                    ans=(ans*2)%mod;
                }
                printf("%d
    ",ans);
            }
        }
        return 0;
    }
  • 相关阅读:
    mv命令(转)
    Linux获得命令帮助(学习笔记五)
    Shell解释器(学习笔记四)
    rmdir 命令(转)
    Java从零开始学十八(抽象类和接口)
    rm 命令(转)
    Centos6.6系统root用户密码恢复案例(转)
    Java从零开始学十七(简单工厂)
    Java从零开始学十六(多态)
    mkdir命令(转)
  • 原文地址:https://www.cnblogs.com/huangdalaofighting/p/7413443.html
Copyright © 2011-2022 走看看