Codeforces Round #311 (Div. 2) D. Vitaly and Cycle(二分图染色,奇环)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #311 (Div. 2) D. Vitaly and Cycle(二分图染色,奇环)相关的知识,希望对你有一定的参考价值。

给定n个点,m条边.

求最少最要加几条边使图中存在奇环,且输出此时加边的方法种数

 

根据题意,只可能为

0:已经存在奇环,dfs搜到已经染色的且颜色相同

 1:判断每个连通块里的 染色黑白色的个数

 2 :某个点的 度 > 1

3:0条边

 

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<queue>
  4 #include<vector>
  5 #include<stack>
  6 #include<set>
  7 #include<string>
  8 #include<cstring>
  9 #include<math.h>
 10 #include<algorithm>
 11 #include<map>
 12 
 13 #include<sstream>
 14 #include<ctype.h>
 15 
 16 #define lson l,m,rt<<1
 17 #define rson m+1,r,rt<<1|1
 18  
 19 typedef long long ll;
 20 using namespace std;
 21  
 22 const int INF = 0x7f7f7f7f;
 23 const double PI = acos(-1.0);
 24 const int maxn = 1005;
 25 const int MOD = (int)1e9+7;
 26 #define LOCAL 0
 27 #define MOD 1000000007
 28 
 29 
 30 /*
 31 0 条边:0 1 
 32 1 条边:
 33 2 条边 m*(n-2) 
 34 3 条边 Cn3 
 35 */
 36 int n,m;
 37 int degree[100005];
 38 vector<int> G[100005];
 39 int color[100005];
 40 int w[100005],b[100005]; 
 41 bool f,f0;
 42 int cnt; // 几个联通块 
 43 void dfs(int u,int c,int num){
 44     color[u] = c;
 45     if(c & 1) w[num]++;
 46     else    b[num]++;
 47     
 48     for(int i = 0 ; i < G[u].size() ; i ++){
 49         int v = G[u][i];
 50         if(!color[v]){
 51             dfs(v,3-c,num);
 52         }else{
 53             if(color[u] == color[v]){
 54                 f0 = true;
 55             }
 56         }
 57     }
 58 }
 59 
 60 void solve(){
 61     // 3条边 
 62     if(m == 0){
 63         printf("%d %I64d\n",3,1LL*n*(n-1)*(n-2)/6);
 64         return ;
 65     }
 66     for(int i = 0 ; i <= n ; i ++) G[i].clear();
 67     memset(degree,0,sizeof(degree));
 68     f = true;
 69     for(int i = 0 ; i < m ; i ++){
 70         int u,v;
 71         scanf("%d%d",&u,&v);
 72         G[u].push_back(v);    degree[u]++;
 73         G[v].push_back(u);    degree[v]++;
 74         if((degree[u] > 1) || (degree[v] > 1))  f = false;
 75     }
 76     // 2 条边
 77     if(f){
 78         printf("2 %I64d\n",1LL*m*(n-2));
 79         return ;
 80     }  
 81     
 82     f0 = false;
 83     cnt = 0;
 84     memset(color,0,sizeof(color));
 85     memset(w,0,sizeof(w));
 86     memset(b,0,sizeof(b));
 87     for(int i = 1 ; i <= n ; i ++){
 88         if(!color[i])
 89             dfs(i,1,cnt++);
 90     }
 91     
 92     // 0条边 
 93     if(f0){
 94         printf("0 1\n");
 95         return;
 96     }
 97     
 98     //1条边
 99     ll ans = 0; 
100     for(int i = 0 ; i < cnt ; i ++){
101         ans = ans + 1LL*w[i]*(w[i]-1)/2 + 1LL*b[i]*(b[i]-1)/2;
102     }
103     printf("1 %I64d\n",ans);
104     return ;
105 }
106 int main(){
107     
108     while(scanf("%d%d",&n,&m) != EOF){
109         solve();
110     }
111     
112     return 0;
113 }

 

以上是关于Codeforces Round #311 (Div. 2) D. Vitaly and Cycle(二分图染色,奇环)的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #311 (Div. 2) D. Vitaly and Cycle(二分图染色,奇环)

Codeforces Round #436 E. Fire(背包dp+输出路径)

[ACM]Codeforces Round #534 (Div. 2)

Codeforces Round #726 (Div. 2) B. Bad Boy(贪心)

CodeForces - 311B:Cats Transport (DP+斜率优化)

Codeforces311 B. Cats Transport(斜率优化dp)