Cycle

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 865    Accepted Submission(s): 241

Problem Description
Ery is interested in graph theory, today he ask BrotherK a problem about it: Given you a undirected graph with N vertexes and M edges, you can select a vertex as your starting point, then you need to walk in the graph along edges. However, you can't pass a edge more than once, even opposite direction is forbidden. At the end, you should come back to the starting point. Assume you has passed X edges, there are two questions:

Question 1: Can X be a odd number ?

Question 2: Can X be a even number ?

(note: you must walk, so X can't be 0)

 
Input
The first line contains a single integer T, indicating the number of test cases.

Each test case begins with two integer N, M, indicating the number of vertexes and the number of edges. Following M lines, each line contains two integers Ui, Vi, indicating there are a edge between vertex Ui and vertex Vi.

T is about 30

1 ≤ N ≤ 100000

0 ≤ M ≤ 300000

1 ≤ Ui,Vi ≤ N

Ui will not equal to Vi

There is at most one edge between any pair of vertex.

 
Output
For each test, print two lines.

The first line contains "YES" or "NO" for question 1.

The second line contains "YES" or "NO" for question 2.

 
Sample Input
3
1 0
3 3
1 2
2 3
3 1
4 4
1 2
2 3
3 4
4 1
 
Sample Output
NO
NO
YES
NO
NO
YES

Hint

If you need a larger stack size,
please use #pragma comment(linker, "/STACK:102400000,102400000") and submit your solution using C++.

 
Source
 

题目大意:给你一个有n个顶点的无向图和m条边,从任意一点出发(经过的边不能再经过),问能否通过走偶数步或者奇数步再回到原点。

思路:首先我们用边双连通分量把所有的符合条件的极大子图都给取出来,然后我们分别对极大子图进行求解。边双连通分量有个特性,不存在和其他的子图有公共点或者公共边。所以我们每次都只要考虑当前子图内部即可。接下来进行分类讨论:

①如果只有一个偶环,或者全都是偶环,那么就是偶数步。 ②如果只有一个奇环,那么就只能走奇数步。③如果子图内有多个奇环或子图内奇偶环都有,那么偶数and奇数都可以。

因此,奇偶环的判定我们就用二分图染色,即可以得到偶环和奇环,并且我们得到奇环以后让cnt++即可,并且不进行return即可。

  1. //看看会不会爆int! 或者绝对值问题。
  2. #include <bits/stdc++.h>
  3. using namespace std;
  4. #pragma comment(linker,"/STACK:102400000,102400000")
  5. #define LL long long
  6. #define pb push_back
  7. #define mk make_pair
  8. #define fi first
  9. #define se second
  10. #define all(a) a.begin(), a.end()
  11. const int maxn = + ;
  12. vector<int> G[maxn], bcc[maxn];
  13. int bccno[maxn], pre[maxn], low[maxn];
  14. int n, m, dfstime, bcc_cnt;
  15. stack<int> s;
  16.  
  17. void dfs(int u, int fa){
  18. low[u] = pre[u] = ++dfstime;
  19. int len = G[u].size();
  20. s.push(u);
  21. for (int i = ; i < len; i++){
  22. int v = G[u][i];
  23. if (pre[v] == -){
  24. dfs(v, u);
  25. low[u] = min(low[u], low[v]);
  26. }
  27. else if(bccno[v] == ){
  28. low[u] = min(low[u], pre[v]);
  29. }
  30. }
  31. if (low[u] == pre[u]){
  32. bcc_cnt++;
  33. while (true){
  34. int x = s.top(); s.pop();
  35. bccno[x] = bcc_cnt;
  36. bcc[bcc_cnt].pb(x);
  37. if (x == u) break;
  38. }
  39. }
  40. return ;
  41. }
  42. int color[maxn], vis[maxn], myodd, myeven;
  43. bool flag;
  44. void draw(int u, int fa){
  45. int len = G[u].size();
  46. for (int i = ; i < len; i++){
  47. int v = G[u][i];
  48. if (bccno[v] != bccno[u]) continue;
  49. if (color[v] != -){
  50. if (v == fa) continue;
  51. if (color[u] == color[v]) {
  52. myodd++;
  53. }
  54. else myeven = ;
  55. }
  56. else {
  57. color[v] = - color[u];
  58. draw(v, u);
  59. }
  60. }
  61. return ;
  62. }
  63.  
  64. int main(){
  65. int t; cin >> t;
  66. while (t--){
  67. scanf("%d%d", &n, &m);
  68. for (int i = ; i <= n; i++) G[i].clear(), bcc[i].clear();
  69. for (int i = ; i <= m; i++){
  70. int u, v; scanf("%d%d", &u, &v);
  71. G[u].pb(v), G[v].pb(u);
  72. }
  73. memset(bccno, , sizeof(bccno));
  74. memset(pre, -, sizeof(pre));
  75. memset(low, -, sizeof(low));
  76. dfstime = bcc_cnt = ;
  77. for (int i = ; i <= n; i++){
  78. if (pre[i] == -){
  79. dfs(i, -);
  80. }
  81. }
  82. memset(color, -, sizeof(color));
  83. ///如果能染色,表示是偶环,反之存在奇环
  84. int odd = , even = ;
  85. for (int i = ; i <= bcc_cnt; i++){
  86. if (bcc[i].size() > ){
  87. myodd = myeven = ;
  88. color[bcc[i][]] = ;
  89. draw(bcc[i][], -);
  90. myodd /= ;
  91. if (myeven == ) even = ;
  92. if (myodd == ) odd = ;
  93. if (myodd > ) even = odd = ;
  94. }
  95. if (odd == && even == ) break;
  96. }
  97. printf("%s\n", odd ? "YES" : "NO");
  98. printf("%s\n", even ? "YES" : "NO");
  99. }
  100. return ;
  101. }
  102.  
  103. /*
  104. 100
  105. 7 8
  106. 1 2
  107. 2 3
  108. 1 3
  109. 2 4
  110. 4 5
  111. 5 6
  112. 6 7
  113. 7 4
  114.  
  115. ans:
  116. yes yes
  117. yes yes
  118. */

学习点:对边连通分量的实际意义的使用

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

  1. ACM 五一杭电赛码"BestCoder"杯中国大学生程序设计冠军赛小记

    对于这项曾经热爱的竞赛,不得不说这是我最后一年参加ACM比赛了,所以要珍惜每一次比赛的机会. 五一去杭电参加了赛码"BestCoder"杯中国大学生程序设计冠军赛,去的队伍包括了今 ...

  2. 个人训练记录-赛码"bestcoder"杯中国大学生程序设计冠军赛

    A.Movie 题意是给n个线段,要求求出是否存在三个不相交的线段,是的话输出yes,否则输出no.根据贪心的想法,可以先找出右端点r'最小的线段,他是三条线段中最左的那条,再找出左端点l'最大的线段 ...

  3. HDU 2242 考研路茫茫——空调教室(边双连通分量+树形dp+重边标号)

    http://acm.hdu.edu.cn/showproblem.php?pid=2242 题意: 思路:首先求一下双连通分量,如果只有一个双连通分量,那么无论断哪根管子,图还是连通的. 最后只需要 ...

  4. HDU - 6440 Dream 2018中国大学生程序设计竞赛 - 网络选拔赛

    给定的\(p\)是素数,要求给定一个加法运算表和乘法运算表,使\((m+n)^p = m^p +n^p(0 \leq m,n < p)\). 因为给定的p是素数,根据费马小定理得 \((m+n) ...

  5. HDU 6235.Permutation (2017中国大学生程序设计竞赛-哈尔滨站-重现赛)

    Permutation Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Tot ...

  6. HDU 5963 朋友 【博弈论】 (2016年中国大学生程序设计竞赛(合肥))

    朋友 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Problem Descr ...

  7. HDU 5969 最大的位或 【贪心】 (2016年中国大学生程序设计竞赛(合肥))

    最大的位或 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Problem De ...

  8. HDU 5968 异或密码 【模拟】 2016年中国大学生程序设计竞赛(合肥)

    异或密码 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Problem Des ...

  9. HDU 5961 传递 【图论+拓扑】 (2016年中国大学生程序设计竞赛(合肥))

    传递 Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)     Problem ...

随机推荐

  1. MySQL 多表查询分页

    SELECT v.*, vt.id vid, vt.vote_id, vt. option, vt.poll FROM vote v JOIN vote_option vt ON v.id = vt. ...

  2. Asynchronous JS: Callbacks, Listeners, Control Flow Libs and Promises

    非常好的文章,讲javascript 的异步编程的. ------------------------------------------------------------------------- ...

  3. (1)Two Sum--求数组中相加为指定值的两个数

    Given an array of integers, find two numbers such that they add up to a specific target number. The ...

  4. 多线程synchronized用例解析

    当用synchronized来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码.即使在执行过程中,CPU切换到别的线程了,因为有锁的缘故,其他线程也不会进来执行代码,而 ...

  5. 八、oracle 分页

    oracle的分页一共有三种方式 方法一 根据rowid来分 SELECT * FROM EMP WHERE ROWID IN (SELECT RID FROM (SELECT ROWNUM RN, ...

  6. JVM垃圾收集算法(标记-清除、复制、标记-整理)

     [JVM垃圾收集算法] 1)标记-清除算法: 标记阶段:先通过根节点,标记所有从根节点开始的对象,未被标记的为垃圾对象(错了吧?) 清除阶段:清除所有未被标记的对象 2)复制算法: 将原有的内存空间 ...

  7. wmic应用实例

    实例应用 1.磁盘管理 查看磁盘的属性 wmic logicaldisk list brief ::caption=标题.driveID=驱动器ID号.model=产品型号.Partitions=分区 ...

  8. 嵌套表SHAPE

    SQL语法 SHAPE {<master query>} APPEND ({ <child table query> } RELATE <master column> ...

  9. Git从远程库克隆

    上次我们讲了先有本地库,后有远程库,如何关联远程库. 现在,假设我们从零开始开发,那么最好的方式就是先创建远程库,然后从远程库克隆. 首先,登录GitHub,创建一个新的仓库,gitskill 创建过 ...

  10. 超赞!聊聊WEB APP、HYBRID APP与NATIVE APP的设计差异

    编者按:这3类主流应用你都了解吗?设计师除了要有视觉功夫,对不同形式的APP也应当了然于胸,今天百度的同学写了一篇非常全面的总结,帮你迅速搞定3类主流APP的设计方法,附带一大波避雷针,带你巧妙跳过A ...