Codeforces 1093D Beautiful Graph|二分图染色

题目链接

蒟蒻第一次通过CF D题~QAQ

言归正传。本题的大意是给每个点赋上$1$、$2$ 、$3$这三种点权之一,使得每条边所连的两个点的点权之和为奇数,问有多少种赋值方案。

首先,我们知道“奇数+偶数=奇数”。显然,凡是能赋值为1的点一定能赋值为3。所以其实我们对于每个点,只有赋值为奇数或偶数两种选择。一旦一条边所连的一个点被赋值为奇数,那么另外一个点就要被赋值为偶数。(有没有发现很像二分图?)

那么,对于每个连通块,我们可以类似用二分图判定的染色法:选定一个起点先行染色,然后用搜索对每个点进行染色。如果染色出现了冲突,整张图的方案数就为$0$。

设此连通块中有$n$个点,$c1$个点被赋值成了奇数,根据乘法原理,这个连通块中赋值方案为$2^{c1}+2^{n-c1}$。($2^{n-c1}$是因为将每个点取反依然可行)同样根据乘法原理,整张图的染色方案是每个联通块的方案数相乘之积。

对于求$2^x$,我们可以用快速幂去求。

上代码

#include<bits/stdc++.h>
using namespace std;
const long long mod=998244353;
int cc,to[900000],net[900000],fr[900000],q[900000],color[900000],ttt,n,m,u,v,h,t;
long long ans,cnt1;
bool vis[900000];
void addedge(int u,int v)
{
    cc++;
    to[cc]=v;net[cc]=fr[u];fr[u]=cc;
}
long long p(int x)
{
//快速幂求2^x
    long long ans=1,kkk=2;
    while (x)
    {
        if (x&1) 
        {
            ans*=kkk;
            ans%=mod;
        }
        kkk*=kkk;
        kkk%=mod;
        x>>=1;
    }
    return ans;
}
int main()
{
    scanf("%d",&ttt);
    for (int tt=1;tt<=ttt;tt++)
    { 
      scanf("%d%d",&n,&m);
      for (int i=1;i<=m;i++)
      {
      	 scanf("%d%d",&u,&v);
      	 addedge(u,v);
      	 addedge(v,u);
      }
      int bb=1;ans=1;
      while (1)
      {
      	 h=1;t=1;q[1]=bb;vis[bb]=1;color[bb]=1;cnt1=1;
      	 while (h<=t)
      	 {
//BFS染色

      	 	 for (int i=fr[q[h]];i;i=net[i])
      	 	 {
      	 	 	int y=to[i];
      	 	 	if (!vis[y])
      	 	 	{
      	 	 		color[y]=3-color[q[h]];
      	 	 		if (color[y]==1) cnt1++; 
      	 	 		q[++t]=to[i];
      	 	 		vis[y]=1;
      	 	 	}
      	 	 	else
      	 	 	{
      	 	 		if (color[y]!=3-color[q[h]]) ans=0;
      	 	 	}
      	 	 }
      	 	 h++;
      	 }
      	 ans*=(p(cnt1)%mod+max(p(t-cnt1),(long long)(1))%mod)%mod;
      	 ans%=mod;
      	 for (int i=bb+1;i<=n;i++)
      	 {
      	 	 if (!vis[i]) {bb=i;break;}//找未被遍历的连通块
      	 }
      	 if (bb==q[1]) break;
      }
      for (int i=1;i<=n;i++)
        fr[i]=0,vis[i]=false,color[i]=0;
      cc=0;
      printf("%d
",ans%mod);
    }
    return 0;
}

  

  Tags:,二分图,图论,快速幂

  

原文地址:https://www.cnblogs.com/fmj123/p/CF1093D.html