标签:
给定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(二分图染色,奇环)
标签:
原文地址:http://www.cnblogs.com/zstu-jack/p/5344525.html