hdu 5215 Cycle
来源:互联网 发布:马爹利鼎盛干邑 知乎 编辑:程序博客网 时间:2024/05/16 02:03
题意:找到一个图中是否含有奇环和偶环
题解:
1.用了两种发法,一个就是跟bc给的答案一样,先求弱联通分量,再在环中找奇偶环
2.我想到的一个稍微省些代码量的方法,边求联通分量,边判断是否含有奇环偶环,奇环一定能判断出来,但是偶环
可能被两个奇数环代替而没有在遍历中发现
3.解决这个问题用到鸽巢定理,先判断有n个联通分量,如果有m个奇环(m > n)则一定有两个奇环在一个连通分量
中,两个奇环可以变成一个偶环,(有个地方需要注意就是:对于单点,当作是一个奇环处理)。
总结:
1.开始想到的解题方法跟标答一样,觉得并不是特别难,写代码的时候感觉特别困,迷迷糊糊的写完了就WA了,睡醒
之后,重新一句一句检查代码,感觉状态不好的时候写的代码简直就是恶心,错误百出,以后状态不好的时候直接休
息
2.后来想到这个优化的方法,写了也WA,第二天才发现题目读错了,这个图可能不是联通的,第一种方法的错误代码
竟然ac了,感觉以后千万不要死扣一个错误,找不到就做会别的事情,再回过头来继续找的时候,也不要局限于一个
小范围,着眼于全局查错!
第一种标答方法:
#pragma comment(linker, "/STACK:102400000,102400000")#include<iostream>#include<cstring>#include<cstdio>#include<algorithm>using namespace std;#define MAXN 100005#define MAXM 300005int n,m,_,e,top,cnt,bcc,odd,even,ans1,ans2;int first[MAXN],dfn[MAXN],stack[MAXN];int id[MAXN],color[MAXN],vis[MAXN];struct Edge{ int next,v;}edge[MAXM << 1];void insert(int u,int v){ edge[e].v = v; edge[e].next = first[u]; first[u] = e++;}void bipartite(int u,int bcc){ for(int i = first[u];i != -1;i = edge[i].next)if(!vis[i] && !vis[i ^ 1]) { int v = edge[i].v; if(id[v] != bcc)continue; vis[i] = vis[i ^ 1] = true; if(color[v] && color[u] != color[v])even++; if(color[u] == color[v])odd++; else if(!color[v]) { color[v] = 3 - color[u]; bipartite(v,bcc); } }}void search(int bcc,int u){ even = odd = 0; color[u] = 1; bipartite(u,bcc); if(odd > 1)even = true; ans1 = max(odd,ans1); ans2 = max(ans2,even);}int dfs(int u,int fa){ int lowu = dfn[u] = ++cnt; stack[++top] = u; for(int i = first[u];i != -1;i = edge[i].next)if((i ^ 1) != fa) { int v = edge[i].v; if(!dfn[v]) { int lowv = dfs(v,i); lowu = min(lowu,lowv); if(dfn[u] < lowv) { bcc++; do { id[stack[top--]] = bcc; }while(stack[top + 1] != v); } } else lowu = min(lowu,dfn[v]); } return lowu;}void solve(){ ans1 = ans2 = 0; memset(dfn,0,sizeof(dfn)); memset(color,0,sizeof(color)); memset(id,0,sizeof(id)); memset(vis,0,sizeof(vis)); bcc = cnt = top = 0; for(int i = 1;i <= n;i++)if(!dfn[i])dfs(1,-1); for(int u = 1;u <= n;u++) if(!color[u]) { search(id[u],u); if(ans1 && ans2)return; }}int main(){ scanf("%d",&_); while(_--) { scanf("%d%d",&n,&m); memset(first,-1,sizeof(first)); e = 0; for(int i = 0;i < m;i++) { int u,v; scanf("%d%d",&u,&v); insert(u,v),insert(v,u); } solve(); if(ans1)puts("YES"); else puts("NO"); if(ans2)puts("YES"); else puts("NO"); }}
优化后的方法:
#pragma comment(linker, "/STACK:102400000,102400000")#include<iostream>#include<cstring>#include<cstdio>#include<algorithm>using namespace std;#define MAXN 100005#define MAXM 300005int n,m,_,e,top,cnt,bcc,odd,even,point;int first[MAXN],dfn[MAXN],stack[MAXN],color[MAXN];bool vis[MAXM << 1];struct Edge{ int next,v;}edge[MAXM << 1];void insert(int u,int v){ edge[e].v = v; edge[e].next = first[u]; first[u] = e++;}int dfs(int u){ int lowu = dfn[u] = ++cnt; stack[++top] = u; for(int i = first[u];i != -1;i = edge[i].next)if(!vis[i] && !vis[i ^ 1]) { int v = edge[i].v; vis[i] = vis[i ^ 1] = true; if(color[v] + color[u] == 3)even++; if(color[u] == color[v])odd++; if(!dfn[v]) { color[v] = 3 - color[u]; int lowv = dfs(v); lowu = min(lowu,lowv); if(dfn[u] < lowv) { bcc++; int num = 0; do { num++; }while(stack[top--] != v); if(num == 1)point++; } } else lowu = min(lowu,dfn[v]); } return lowu;}void solve(){ even = odd = point = 0; memset(dfn,0,sizeof(dfn)); memset(color,0,sizeof(color)); memset(vis,false,sizeof(vis)); bcc = 0; cnt = top = 0; for(int i = 1;i <= n;i++)if(!dfn[i]) { bcc++; color[i] = 1; dfs(i); } if(top == 1)point++; if(point + odd > bcc)even++;}int main(){ scanf("%d",&_); while(_--) { scanf("%d%d",&n,&m); memset(first,-1,sizeof(first)); e = 0; for(int i = 0;i < m;i++) { int u,v; scanf("%d%d",&u,&v); insert(u,v),insert(v,u); } solve(); if(odd)puts("YES"); else puts("NO"); if(even)puts("YES"); else puts("NO"); }}
0 0
- hdu 5215 Cycle
- hdu 5215 Cycle
- HDU 5215 Cycle (搜索)
- hdu 5215 Cycle (图论,盘环)
- HDU 5215 Cycle --- 奇偶环的判定
- HDU 5782 Cycle
- HDU 5215 Cycle(判定无向图奇偶环)
- HDU - 5215 Cycle(奇圈和偶圈)
- HDU 1700 Points on Cycle
- HDU-1700 Points on Cycle
- hdu 5215 Cycle(判断是否有奇数偶数的环)
- [二分图染色判奇偶换 || 并查集] HDU 5215 Cycle
- HDOJ 5215 Cycle
- hdu 1700 Points on Cycle 水几何
- hdu 1700 Points on Cycle(几何)(中等)
- [HDU 5782] Cycle (bitset优化+脑洞)
- HDU 5782 Cycle(后缀数组+bitset)
- Hdu 5782 Cycle(拓展KMP+Hash)
- Android studio使用git提交但是没有push,如何回退并保存
- 【线段树】 HDOJ 5274 Dylans loves tree
- DateTime
- 第四章
- 第五章
- hdu 5215 Cycle
- android中关于tools:context="activity name"解惑
- 第六章
- mysql字段去重方式
- Android基本控件之TextView和EditView
- Quick Reference:php5 Xdebug 代码覆盖分析
- 第七章
- 2015半年总结,我要实现的个人目标
- LabWindows/CVI 下载