hdu 5215
判断图中是否含有奇环或者偶环
二分图的染色思想 + 胡搞
记住。。如果一图是二分图,那么它一定没有奇环。如果一图没有奇环的话,那么它可以是二分图。
c++提交, 不加黑科技要爆栈。。
大牛的DFS http://www.cnblogs.com/vb4896/p/4500177.html
1 void Dfs(int x,int c) 2 { 3 int y; vis[x]=instack[x]=true,color[x]=c; 4 for (int i=head[x];i!=-1;i=nxt[i]) 5 { 6 y=to[i]; if (y==father[x]) continue; 7 if (!vis[y]) 8 { 9 father[y]=x; 10 Dfs(y,c^1); 11 Odd[x]+=Odd[y]; 12 Even[x]+=Even[y]; 13 } 14 else 15 { 16 if (instack[y]) 17 { 18 if (color[x]==color[y]) Odd[x]++; 19 else Even[x]++; 20 } 21 else 22 { 23 if (color[x]==color[y]) Odd[father[x]]--; 24 else Even[father[x]]--; 25 } 26 } 27 } 28 if (Even[x] || Odd[x]>=2) flag2=true; 29 if (Odd[x]) flag1=true; 30 instack[x]=false; 31 }
参考BC别人的AC的代码 o(╯□╰)o
1 /*Author :usedrose */ 2 /*Created Time :2015/7/31 15:14:40*/ 3 /*File Name :2.cpp*/ 4 #pragma comment(linker, "/STACK:1024000000,1024000000") 5 #include <cstdio> 6 #include <iostream> 7 #include <algorithm> 8 #include <sstream> 9 #include <cstdlib> 10 #include <cstring> 11 #include <climits> 12 #include <vector> 13 #include <string> 14 #include <ctime> 15 #include <cmath> 16 #include <deque> 17 #include <queue> 18 #include <stack> 19 #include <set> 20 #include <map> 21 #define INF 0x3f3f3f3f 22 #define eps 1e-8 23 #define pi acos(-1.0) 24 #define MAXN 200110 25 #define OK cout << "ok" << endl; 26 #define o(a) cout << #a << " = " << a << endl 27 #define o1(a,b) cout << #a << " = " << a << " " << #b << " = " << b << endl 28 using namespace std; 29 typedef long long LL; 30 31 struct E{ 32 E(int u, int nx) { 33 v = u, nxt = nx; 34 } 35 E(){} 36 int v, nxt; 37 }edge[600010]; 38 39 bool even, odd; 40 int n, m, head[MAXN], col[MAXN], pre[MAXN], tot, cnt; 41 vector<int> bel[MAXN]; 42 43 void init() 44 { 45 cnt = tot = even = odd = 0; 46 memset(col, 0, sizeof(col)); 47 memset(head, -1, sizeof(head)); 48 for (int i = 0; i <= n; ++i) { 49 bel[i].clear(); 50 } 51 } 52 53 void addedge(int u, int v) 54 { 55 edge[tot] = E(v, head[u]); 56 head[u] = tot++; 57 } 58 59 void dfs(int u, int fa) 60 { 61 for (int i = head[u]; i != -1; i = edge[i].nxt) 62 { 63 if ((i ^ 1) == fa) continue; 64 int v = edge[i].v; 65 //如果与访问过的节点颜色相同,说明存在奇环,然后把所有在奇环上的点所在环的个数记录一下 66 if (col[v] == col[u]) { 67 odd = 1; 68 ++cnt; 69 int x = v; 70 while (!even) 71 { 72 bel[x].push_back(cnt); 73 if (bel[x].size() > 1) 74 even = true; 75 x = pre[x]; 76 if (x == u || x == -1) break; 77 } 78 } 79 //如果其他节点已经访问过, 并且颜色不想同, 说明存在偶环 80 if (col[v] == 3 - col[u]) 81 even = 1; 82 if (!col[v]) { 83 col[v] = 3 - col[u]; 84 pre[v] = u; 85 dfs(v, i); 86 } 87 } 88 } 89 90 int main() 91 { 92 //freopen("data.in","r",stdin); 93 //freopen("data.out","w",stdout); 94 int T; 95 scanf("%d", &T); 96 while (T--) { 97 scanf("%d%d", &n, &m); 98 init(); 99 int u, v; 100 while (m--) { 101 scanf("%d%d", &u, &v); 102 addedge(u, v); 103 addedge(v, u); 104 } 105 for (int i = 1; i <= n; ++i) 106 if (!col[i]) { 107 col[i] = 1; 108 pre[i] = -1; 109 dfs(i, -1); 110 } 111 puts(odd ? "YES" : "NO"); 112 puts(even ? "YES" : "NO"); 113 } 114 return 0; 115 }