灰狼呼唤着同胞(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\n");
        else
        {
            int ans=1;
            for(i=1;i<cnt;i++)
            {
                ans=(ans*2)%mod;
            }
            printf("%d\n",ans);
        }
    }
    return 0;
}

 

posted @ 2017-08-22 20:10  kakakakakaka  阅读(230)  评论(0编辑  收藏  举报

Never forget why you start

//鼠标爆炸特效