codeforces 557D Vitaly and Cycle
新技能get
二分图染色居然可以用来判断奇偶环。。
如果能构成二分图,说明没有奇环
对于任意二分图,其包含的环一定全部是偶环!(充要可证)
可以证明,含有奇数条边的环一定有两个在相同集合内的点有边相连!
也就是说——二分图的bfs子树一定不含奇环!
下面讨论摘自http://www.cnblogs.com/sagitta/p/4612214.html
首先讨论添加边条数为3——即原原图边数m为0时
ns=n*(n-1)*(n-2)/6
再讨论添加边条数为2——即原图中所有边都没有公共端点/所有点度数<=1 时
ans=m*(n-2)
再讨论添加边数为0——即原图中存在奇环时
ans=1
最后讨论添加边数为1——即原图中只有树以及偶环
ans=Σ[ (white[i]-1)*white[i]/2+(black[i]-1)*black[i]/2 ]
看的matrix大牛代码
dfs中直接求ans
1 /*Author :usedrose */ 2 /*Created Time :2015/7/19 17:01:15*/ 3 /*File Name :2.cpp*/ 4 #include <cstdio> 5 #include <iostream> 6 #include <algorithm> 7 #include <sstream> 8 #include <cstdlib> 9 #include <cstring> 10 #include <climits> 11 #include <vector> 12 #include <string> 13 #include <ctime> 14 #include <cmath> 15 #include <deque> 16 #include <queue> 17 #include <stack> 18 #include <set> 19 #include <map> 20 #define INF 0x3f3f3f3f 21 #define eps 1e-8 22 #define pi acos(-1.0) 23 #define MAXN 100110 24 #define OK cout << "ok" << endl; 25 #define o(a) cout << #a << " = " << a << endl 26 #define o1(a,b) cout << #a << " = " << a << " " << #b << " = " << b << endl 27 using namespace std; 28 typedef long long LL; 29 30 int n, m; 31 bool marked[MAXN], ok; 32 int sz[2]; 33 int col[MAXN]; 34 vector<int > G[MAXN]; 35 LL ans; 36 37 void dfs(int v, int c) 38 { 39 marked[v] = true; 40 ans += sz[c-1]; 41 sz[c-1]++; 42 col[v] = c; 43 for (int i = 0; i < G[v].size(); i++) 44 { 45 int u = G[v][i]; 46 if (!marked[u]) 47 { 48 col[u] = 3 - c; 49 dfs(u, 3 - c); 50 } 51 else if (col[u] == col[v]) 52 ok = true; 53 } 54 } 55 int main() 56 { 57 //freopen("data.in","r",stdin); 58 //freopen("data.out","w",stdout); 59 cin.tie(0); 60 ios::sync_with_stdio(false); 61 cin >> n >> m; 62 int a, b; 63 64 for (int i = 0;i < m; ++ i) { 65 cin >> a >> b; 66 G[a].push_back(b); 67 G[b].push_back(a); 68 } 69 for (int i = 1; i <= n; ++ i) 70 if (!marked[i]) { 71 sz[0] = sz[1] = 0; 72 dfs(i, 1); 73 } 74 if (ok) 75 cout << 0 << " " << 1 << endl; 76 else if (ans == 0) 77 { 78 if (m == 0) 79 { 80 long long ans = n; 81 ans *= n - 1; 82 ans *= n - 2; 83 ans /= 6; 84 cout << 3 << " " << ans << endl; 85 } 86 else 87 cout << 2 << " " << (long long)m * (n - 2) << endl; 88 89 } 90 else 91 cout << 1 << " " << ans << endl; 92 93 return 0; 94 }
待做。。
http://www.hardbird.net/hdu-5215-cycle%E4%BA%8C%E5%88%86%E5%9B%BE%E6%9F%93%E8%89%B2%E5%88%A4%E5%A5%87%E5%81%B6%E7%8E%AF/