Codeforces 1093D Beautiful Graph(二分图染色+计数)

题目链接:Beautiful Graph

题意:给定一张无向无权图,每个顶点可以赋值1,2,3,现要求相邻节点一奇一偶,求符合要求的图的个数。

题解:由于一奇一偶,需二分图判定,染色。判定失败,直接输出0。成功的话,统计下奇数(cnt1)和偶数(cnt2)顶点个数,只有奇数有两种,也就是说有$2^{cnt1}$种,但是可以把奇数和偶数顶点翻转,奇变偶,偶变奇,即最后有$2^{cnt1}+2^{cnt2}$种,注意此图可能不连通,各个图之间的答案数要相乘。

 1 #include <set>
 2 #include <map>
 3 #include <queue>
 4 #include <deque>
 5 #include <stack>
 6 #include <cmath>
 7 #include <cstdio>
 8 #include <vector>
 9 #include <string>
10 #include <cstring>
11 #include <fstream>
12 #include <iostream>
13 #include <algorithm>
14 using namespace std;
15 
16 #define eps 1e-8
17 #define pb push_back
18 #define PI acos(-1.0)
19 #define INF 0x3f3f3f3f
20 #define clr(a,b) memset(a,b,sizeof(a)
21 #define FAST_IO ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
22 
23 const int N=3e5+10;
24 typedef long long ll;
25 typedef unsigned long long ull;
26 bool f;
27 int col[N];
28 ll p1=0,p2=0;
29 const ll mod=998244353;
30 vector <int> E[N];
31 
32 void dfs(int u){
33     if(col[u]==1) p1++;
34     else p2++;
35     for(int i=0;i<E[u].size();i++){
36         int v=E[u][i];
37         if(!col[v]){
38             if(col[u]==1) col[v]=2;
39             else if(col[u]==2) col[v]=1;
40             dfs(v);
41         }
42         else if(col[u]==col[v]) f=0;
43     }
44 }
45 
46 ll fast_mod(ll a,ll b){
47     ll res=1;
48     while(b){
49         if(b&1) res=(res*a)%mod;
50         b>>=1;
51         a=(a*a)%mod;
52     }
53     return res;
54 }
55 
56 int main(){
57     FAST_IO;
58     int t,n,m;
59     cin>>t;
60     while(t--){
61         f=1;
62         ll ans=1;
63         cin>>n>>m;
64         for(int i=1;i<=m;i++){
65             int u,v;
66             cin>>u>>v;
67             E[u].push_back(v);
68             E[v].push_back(u);
69         }
70         for(int i=1;i<=n;i++){
71             if(!col[i]){
72                 col[i]=1;
73                 p1=0;p2=0;
74                 dfs(i);
75                 ans=ans*((fast_mod(2,p1)+fast_mod(2,p2))%mod)%mod;
76             }
77         }
78         if(!f) cout<<0<<endl;
79         else cout<<ans<<endl;
80         for(int i=1;i<=n;i++) E[i].clear(),col[i]=0;
81     }
82     return 0;
83 }
View Code

 

转载于:https://www.cnblogs.com/ehanla/p/10126035.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值