题意:找到一个图中是否含有奇环和偶环

题解:

1.用了两种发法。一个就是跟bc给的答案一样,先求弱联通分量。再在环中找奇偶环

2.我想到的一个略微省些代码量的方法。边求联通分量,边推断是否含有奇环偶环。奇环一定能推断出来,可是偶环

可能被两个奇数环取代而没有在遍历中发现

3.解决问题用到鸽巢定理。先推断有n个联通分量。假设有m个奇环(m > n)则一定有两个奇环在一个连通分量

中,两个奇环可以变成一个偶环,(有个地方须要注意就是:对于单点。当作是一个奇环处理)。

总结:

1.開始想到的解题方法跟标答一样,认为并非特别难,写代码的时候感觉特别困。迷迷糊糊的写完了就WA了,睡醒

之后,又一次一句一句检查代码,感觉状态不好的时候写的代码简直就是恶心,错误百出,以后状态不好的时候直接休

2.后来想到这个优化的方法,写了也WA,第二天才发现题目读错了。这个图可能不是联通的,第一种方法的错误代码

居然ac了,感觉以后千万不要死扣一个错误,找不到就做会别的事情。再回过头来继续找的时候。也不要局限于一个

小范围。着眼于全局查错!

第一种标答方法:

  1. #pragma comment(linker, "/STACK:102400000,102400000")
  2. #include<iostream>
  3. #include<cstring>
  4. #include<cstdio>
  5. #include<algorithm>
  6. using namespace std;
  7. #define MAXN 100005
  8. #define MAXM 300005
  9. int n,m,_,e,top,cnt,bcc,odd,even,ans1,ans2;
  10. int first[MAXN],dfn[MAXN],stack[MAXN];
  11. int id[MAXN],color[MAXN],vis[MAXN];
  12. struct Edge
  13. {
  14. int next,v;
  15. }edge[MAXM << 1];
  16. void insert(int u,int v)
  17. {
  18. edge[e].v = v;
  19. edge[e].next = first[u];
  20. first[u] = e++;
  21. }
  22. void bipartite(int u,int bcc)
  23. {
  24. for(int i = first[u];i != -1;i = edge[i].next)if(!vis[i] && !vis[i ^ 1])
  25. {
  26. int v = edge[i].v;
  27. if(id[v] != bcc)continue;
  28. vis[i] = vis[i ^ 1] = true;
  29. if(color[v] && color[u] != color[v])even++;
  30. if(color[u] == color[v])odd++;
  31. else if(!color[v])
  32. {
  33. color[v] = 3 - color[u];
  34. bipartite(v,bcc);
  35. }
  36. }
  37. }
  38. void search(int bcc,int u)
  39. {
  40. even = odd = 0;
  41. color[u] = 1;
  42. bipartite(u,bcc);
  43. if(odd > 1)even = true;
  44. ans1 = max(odd,ans1);
  45. ans2 = max(ans2,even);
  46. }
  47. int dfs(int u,int fa)
  48. {
  49. int lowu = dfn[u] = ++cnt;
  50. stack[++top] = u;
  51. for(int i = first[u];i != -1;i = edge[i].next)if((i ^ 1) != fa)
  52. {
  53. int v = edge[i].v;
  54. if(!dfn[v])
  55. {
  56. int lowv = dfs(v,i);
  57. lowu = min(lowu,lowv);
  58. if(dfn[u] < lowv)
  59. {
  60. bcc++;
  61. do
  62. {
  63. id[stack[top--]] = bcc;
  64. }while(stack[top + 1] != v);
  65. }
  66. }
  67. else lowu = min(lowu,dfn[v]);
  68. }
  69. return lowu;
  70. }
  71. void solve()
  72. {
  73. ans1 = ans2 = 0;
  74. memset(dfn,0,sizeof(dfn));
  75. memset(color,0,sizeof(color));
  76. memset(id,0,sizeof(id));
  77. memset(vis,0,sizeof(vis));
  78. bcc = cnt = top = 0;
  79. for(int i = 1;i <= n;i++)if(!dfn[i])dfs(1,-1);
  80. for(int u = 1;u <= n;u++)
  81. if(!color[u])
  82. {
  83. search(id[u],u);
  84. if(ans1 && ans2)return;
  85. }
  86. }
  87. int main()
  88. {
  89. scanf("%d",&_);
  90. while(_--)
  91. {
  92. scanf("%d%d",&n,&m);
  93. memset(first,-1,sizeof(first));
  94. e = 0;
  95. for(int i = 0;i < m;i++)
  96. {
  97. int u,v;
  98. scanf("%d%d",&u,&v);
  99. insert(u,v),insert(v,u);
  100. }
  101. solve();
  102. if(ans1)puts("YES");
  103. else puts("NO");
  104. if(ans2)puts("YES");
  105. else puts("NO");
  106. }
  107. }

优化后的方法:

  1. #pragma comment(linker, "/STACK:102400000,102400000")
  2. #include<iostream>
  3. #include<cstring>
  4. #include<cstdio>
  5. #include<algorithm>
  6. using namespace std;
  7. #define MAXN 100005
  8. #define MAXM 300005
  9. int n,m,_,e,top,cnt,bcc,odd,even,point;
  10. int first[MAXN],dfn[MAXN],stack[MAXN],color[MAXN];
  11. bool vis[MAXM << 1];
  12. struct Edge
  13. {
  14. int next,v;
  15. }edge[MAXM << 1];
  16. void insert(int u,int v)
  17. {
  18. edge[e].v = v;
  19. edge[e].next = first[u];
  20. first[u] = e++;
  21. }
  22. int dfs(int u)
  23. {
  24. int lowu = dfn[u] = ++cnt;
  25. stack[++top] = u;
  26. for(int i = first[u];i != -1;i = edge[i].next)if(!vis[i] && !vis[i ^ 1])
  27. {
  28. int v = edge[i].v;
  29. vis[i] = vis[i ^ 1] = true;
  30. if(color[v] + color[u] == 3)even++;
  31. if(color[u] == color[v])odd++;
  32. if(!dfn[v])
  33. {
  34. color[v] = 3 - color[u];
  35. int lowv = dfs(v);
  36. lowu = min(lowu,lowv);
  37. if(dfn[u] < lowv)
  38. {
  39. bcc++;
  40. int num = 0;
  41. do
  42. {
  43. num++;
  44. }while(stack[top--] != v);
  45. if(num == 1)point++;
  46. }
  47. }
  48. else lowu = min(lowu,dfn[v]);
  49. }
  50. return lowu;
  51. }
  52. void solve()
  53. {
  54. even = odd = point = 0;
  55. memset(dfn,0,sizeof(dfn));
  56. memset(color,0,sizeof(color));
  57. memset(vis,false,sizeof(vis));
  58. bcc = 0;
  59. cnt = top = 0;
  60. for(int i = 1;i <= n;i++)if(!dfn[i])
  61. {
  62. bcc++;
  63. color[i] = 1;
  64. dfs(i);
  65. }
  66. if(top == 1)point++;
  67. if(point + odd > bcc)even++;
  68. }
  69. int main()
  70. {
  71. scanf("%d",&_);
  72. while(_--)
  73. {
  74. scanf("%d%d",&n,&m);
  75. memset(first,-1,sizeof(first));
  76. e = 0;
  77. for(int i = 0;i < m;i++)
  78. {
  79. int u,v;
  80. scanf("%d%d",&u,&v);
  81. insert(u,v),insert(v,u);
  82. }
  83. solve();
  84. if(odd)puts("YES");
  85. else puts("NO");
  86. if(even)puts("YES");
  87. else puts("NO");
  88. }
  89. }

hdu 5215 Cycle的更多相关文章

  1. HDU.5215.Cycle(判环)

    题目链接 \(Description\) 给定\(n\)个点\(m\)条边的无向图,问是否存在一个长度为奇数/偶数的简单环. \(n\leq 10^5,m\leq 3\times 10^5\). \( ...

  2. HDU 5215 Cycle(dfs判环)

    题意 题目链接 \(T\)组数据,给出\(n\)个点\(m\)条边的无向图,问是否存在一个奇环/偶环 Sol 奇环比较好判断吧,直接判是否是二分图就行了.. 偶环看起来很显然就是如果dfs到一个和他颜 ...

  3. HDU 5782 Cycle —— KMP

    题目:Cycle 链接:http://acm.hdu.edu.cn/showproblem.php?pid=5782 题意:给出两个字符串,判断两个字符串的每一个前缀是否循环相等(比如abc 和 ca ...

  4. HDU 5782 Cycle(KMP+Hash)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5782 [题目大意] 给出两个字符串,判断他们每一个前缀是否循环同构,循环同构的意思就是,字符串首位 ...

  5. HDU 5215 BestCoder"杯中国大学生程序设计冠军赛” 边双连通分量取出子图+二分染色判图内奇偶环

    Cycle Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Sub ...

  6. HDU 5782 Cycle(KMP+哈希)

    http://acm.split.hdu.edu.cn/showproblem.php?pid=5782 题意:给出两个长度相等的字符串,输出两个字符的每个前缀是否循环相同. 思路: 如果连个串循环相 ...

  7. HDU 6987 - Cycle Binary(找性质+杜教筛)

    题面传送门 首先 mol 一发现场 AC 的 csy 神仙 为什么这题现场这么多人过啊啊啊啊啊啊 继续搬运官方题解( 首先对于题目中的 \(k,P\)​,我们有若存在字符串 \(k,P,P'\)​ 满 ...

  8. 2015 "BestCoder Cup" Champion

    这场比赛我没有参加,不过就算参加了也估计是被完虐.于是看着题解把大部分题目都搞了一遍. T1:Movie(hdu 5214) 题目大意: 给出N个区间,问能否选出3个互不相交的区间. N<=10 ...

  9. 莫比乌斯反演&各种筛法

    不学莫反,不学狄卷,就不能叫学过数论 事实上大概也不是没学过吧,其实上赛季头一个月我就在学这东西,然鹅当时感觉没学透,连杜教筛复杂度都不会证明,所以现在只好重新来学一遍了(/wq 真·实现了水平的负增 ...

随机推荐

  1. PHP一些优先级的问题

    直接看代码 <?php echo '1'.print(2)+3,"\n"; 不错,就是这么简单,但是很少有人能正确回答 我们执行一下 [root@localhost test ...

  2. 使用Dockerfile文件构建基于centOS系统的tomcat镜像

    以下是Dockerfile的内容: #基础镜像 FROM centos #维护人员信息 MAINTAINER weigs "weigs1231@gmail.com" #设置工作目录 ...

  3. dom 解析xml文件

    JAXP技术 JAXP即Java Api for Xml Processing该API主要是SUN提供的用于解析XML数据的一整套解决方案,主要包含了DOM和SAX解析技术.大家可以参见SUN的以下两 ...

  4. [ubuntu]为ubuntu设立“任务管理器”的组合键

    在windows下面,我们可以方便的使用ctrl+alt+delete调出任务管理器,那么在ubuntu下面如何实现呢?这里我们介绍两种方法:1.在终端下运行: 代码:gconf-editor 找到: ...

  5. 理解WEB标准

    WEB标准不是某一个标准,而是一系列标准的集合.网页主要由三部分组成:结构(Structure).表现(Presentation)和行为 (Behavior).对应的标准也分三方面:结构化标准语言主要 ...

  6. 【LeetCode】164. Maximum Gap (2 solutions)

    Maximum Gap Given an unsorted array, find the maximum difference between the successive elements in ...

  7. 快速掌握activity的生命周期

    activity的生命周期不管是在面试还是在工作中我们都会经常遇到,这当然也是非常基础的,基础也很重要哦,学会activity的生命周期对我们以后开发更健壮的程序会有很大帮助.下面来看一下Activi ...

  8. JS取date的前一天时间

    在javascript中取date的前一天时间: new Date(new Date()-24*60*60*1000),//取前一天的时间

  9. iOS CPU占有率达到了100%甚至更多,然后导致App闪退

    今天在真机调试的过程中,发现了一个严重的问题,发现CPU的使用率竟然达到了100%,以至于会导致运行内存占用过高,被系统的看门狗机制给杀掉. 下面就讲一讲怎么去定位这个问题: 1.打开Xcode,把项 ...

  10. 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 ...