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 }