hdu 5215 Cycle
题意:找到一个图中是否含有奇环和偶环
题解:
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 300005
- int 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 300005
- int 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");
- }
- }
hdu 5215 Cycle的更多相关文章
- HDU.5215.Cycle(判环)
题目链接 \(Description\) 给定\(n\)个点\(m\)条边的无向图,问是否存在一个长度为奇数/偶数的简单环. \(n\leq 10^5,m\leq 3\times 10^5\). \( ...
- HDU 5215 Cycle(dfs判环)
题意 题目链接 \(T\)组数据,给出\(n\)个点\(m\)条边的无向图,问是否存在一个奇环/偶环 Sol 奇环比较好判断吧,直接判是否是二分图就行了.. 偶环看起来很显然就是如果dfs到一个和他颜 ...
- HDU 5782 Cycle —— KMP
题目:Cycle 链接:http://acm.hdu.edu.cn/showproblem.php?pid=5782 题意:给出两个字符串,判断两个字符串的每一个前缀是否循环相等(比如abc 和 ca ...
- HDU 5782 Cycle(KMP+Hash)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5782 [题目大意] 给出两个字符串,判断他们每一个前缀是否循环同构,循环同构的意思就是,字符串首位 ...
- HDU 5215 BestCoder"杯中国大学生程序设计冠军赛” 边双连通分量取出子图+二分染色判图内奇偶环
Cycle Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Sub ...
- HDU 5782 Cycle(KMP+哈希)
http://acm.split.hdu.edu.cn/showproblem.php?pid=5782 题意:给出两个长度相等的字符串,输出两个字符的每个前缀是否循环相同. 思路: 如果连个串循环相 ...
- HDU 6987 - Cycle Binary(找性质+杜教筛)
题面传送门 首先 mol 一发现场 AC 的 csy 神仙 为什么这题现场这么多人过啊啊啊啊啊啊 继续搬运官方题解( 首先对于题目中的 \(k,P\),我们有若存在字符串 \(k,P,P'\) 满 ...
- 2015 "BestCoder Cup" Champion
这场比赛我没有参加,不过就算参加了也估计是被完虐.于是看着题解把大部分题目都搞了一遍. T1:Movie(hdu 5214) 题目大意: 给出N个区间,问能否选出3个互不相交的区间. N<=10 ...
- 莫比乌斯反演&各种筛法
不学莫反,不学狄卷,就不能叫学过数论 事实上大概也不是没学过吧,其实上赛季头一个月我就在学这东西,然鹅当时感觉没学透,连杜教筛复杂度都不会证明,所以现在只好重新来学一遍了(/wq 真·实现了水平的负增 ...
随机推荐
- PHP一些优先级的问题
直接看代码 <?php echo '1'.print(2)+3,"\n"; 不错,就是这么简单,但是很少有人能正确回答 我们执行一下 [root@localhost test ...
- 使用Dockerfile文件构建基于centOS系统的tomcat镜像
以下是Dockerfile的内容: #基础镜像 FROM centos #维护人员信息 MAINTAINER weigs "weigs1231@gmail.com" #设置工作目录 ...
- dom 解析xml文件
JAXP技术 JAXP即Java Api for Xml Processing该API主要是SUN提供的用于解析XML数据的一整套解决方案,主要包含了DOM和SAX解析技术.大家可以参见SUN的以下两 ...
- [ubuntu]为ubuntu设立“任务管理器”的组合键
在windows下面,我们可以方便的使用ctrl+alt+delete调出任务管理器,那么在ubuntu下面如何实现呢?这里我们介绍两种方法:1.在终端下运行: 代码:gconf-editor 找到: ...
- 理解WEB标准
WEB标准不是某一个标准,而是一系列标准的集合.网页主要由三部分组成:结构(Structure).表现(Presentation)和行为 (Behavior).对应的标准也分三方面:结构化标准语言主要 ...
- 【LeetCode】164. Maximum Gap (2 solutions)
Maximum Gap Given an unsorted array, find the maximum difference between the successive elements in ...
- 快速掌握activity的生命周期
activity的生命周期不管是在面试还是在工作中我们都会经常遇到,这当然也是非常基础的,基础也很重要哦,学会activity的生命周期对我们以后开发更健壮的程序会有很大帮助.下面来看一下Activi ...
- JS取date的前一天时间
在javascript中取date的前一天时间: new Date(new Date()-24*60*60*1000),//取前一天的时间
- iOS CPU占有率达到了100%甚至更多,然后导致App闪退
今天在真机调试的过程中,发现了一个严重的问题,发现CPU的使用率竟然达到了100%,以至于会导致运行内存占用过高,被系统的看门狗机制给杀掉. 下面就讲一讲怎么去定位这个问题: 1.打开Xcode,把项 ...
- clscfg.bin: error while loading shared libraries: libcap.so.1:
RAC安装过程中,安装GI,运行root.sh脚本时报如下错误: # /u01/app//grid/root.sh Running Oracle 11g root script... The foll ...