题目链接:http://poj.org/problem?id=2762

题意是 有t组样例,n个点m条有向边,取任意两个点u和v,问u能不能到v 或者v能不能到u,要是可以就输出Yes,否则输出No。注意一点,条件是或者!所以不是判断双连通图的问题。

我一开始没看到'or'这个条件,所以直接tarjan判断是否只有一个强连通分量,果断WA。

所以需要给原图缩点,用tarjan把图变成一个有向无环图,要是只有一个scc,那就直接输出Yes。那接下来讨论多个scc,要是新图中有两个及以上的点的入度为0,则这些点都不能相互到达,所以输出No,所以我们找到唯一一个入度为0的点作为root,然后从这个点来拓扑排序,出队入队的过程肯定是一进一出的,所以根据过程来判断是否输出Yes和No。

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <vector>
  5. #include <queue>
  6. using namespace std;
  7. const int MAXN = ;
  8. struct data {
  9. int next , to;
  10. }edge[MAXN * ];
  11. int head[MAXN] , st[MAXN] , low[MAXN] , dfn[MAXN] , block[MAXN] , du[MAXN];
  12. int top , ord , sccnum , cont;
  13. bool instack[MAXN];
  14. vector <int> G[MAXN];
  15.  
  16. inline void add(int u , int v) {
  17. edge[cont].next = head[u];
  18. edge[cont].to = v;
  19. head[u] = cont++;
  20. }
  21.  
  22. void init() {
  23. memset(head , - , sizeof(head));
  24. memset(dfn , , sizeof(dfn));
  25. memset(du , , sizeof(du));
  26. memset(instack , false , sizeof(instack));
  27. top = sccnum = ord = cont = ;
  28. }
  29.  
  30. void tarjan(int u) {
  31. low[u] = dfn[u] = ++ord;
  32. st[++top] = u;
  33. instack[u] = true;
  34. for(int i = head[u] ; ~i ; i = edge[i].next) {
  35. int v = edge[i].to;
  36. if(!dfn[v]) {
  37. tarjan(v);
  38. low[u] = min(low[u] , low[v]);
  39. }
  40. else if(instack[v]) {
  41. low[u] = min(low[u] , low[v]);
  42. }
  43. }
  44. if(low[u] == dfn[u]) {
  45. int v;
  46. sccnum++;
  47. do {
  48. v = st[top--];
  49. instack[v] = false;
  50. block[v] = sccnum;
  51. }while(u != v);
  52. }
  53. }
  54.  
  55. void top_sort() {
  56. queue <int> que;
  57. while(!que.empty()) {
  58. que.pop();
  59. }
  60. cont = ;
  61. for(int i = ; i <= sccnum ; i++) {
  62. if(!du[i]) {
  63. que.push(i);
  64. cont++;
  65. }
  66. }
  67. if(cont > ) {
  68. printf("No\n");
  69. return ;
  70. }
  71. while(!que.empty()) {
  72. int temp = que.front() , cnt = ;
  73. que.pop();
  74. for(int i = ; i < G[temp].size() ; i++) {
  75. du[G[temp][i]]--;
  76. if(!du[G[temp][i]]) {
  77. cnt++;
  78. cont++;
  79. que.push(G[temp][i]);
  80. }
  81. }
  82. if(cnt > ) {
  83. printf("No\n");
  84. return ;
  85. }
  86. }
  87. if(cont != sccnum) {
  88. printf("No\n");
  89. }
  90. else {
  91. printf("Yes\n");
  92. }
  93. }
  94.  
  95. int main()
  96. {
  97. int t , n , m , u , v;
  98. scanf("%d" , &t);
  99. while(t--) {
  100. scanf("%d %d" , &n , &m);
  101. init();
  102. for(int i = ; i < m ; i++) {
  103. scanf("%d %d" , &u , &v);
  104. add(u , v);
  105. }
  106. for(int i = ; i <= n ; i++) {
  107. G[i].clear();
  108. if(!dfn[i])
  109. tarjan(i);
  110. }
  111. if(sccnum == ) {
  112. printf("Yes\n");
  113. continue;
  114. }
  115. for(int u = ; u <= n ; u++) {
  116. for(int i = head[u] ; ~i ; i = edge[i].next) {
  117. int v = edge[i].to;
  118. if(block[u] != block[v]) {
  119. du[block[v]]++;
  120. G[block[u]].push_back(block[v]);
  121. }
  122. }
  123. }
  124. top_sort();
  125. }
  126. }

POJ 2762 Going from u to v or from v to u? (强连通分量缩点+拓扑排序)的更多相关文章

  1. poj 2762 Going from u to v or from v to u?【强连通分量缩点+拓扑排序】

    Going from u to v or from v to u? Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 15812 ...

  2. POJ2762 Going from u to v or from v to u? 强连通分量缩点+拓扑排序

    题目链接:https://vjudge.net/contest/295959#problem/I 或者 http://poj.org/problem?id=2762 题意:输入多组样例,输入n个点和m ...

  3. POJ2762 Going from u to v or from v to u?(判定单连通图:强连通分量+缩点+拓扑排序)

    这道题要判断一张有向图是否是单连通图,即图中是否任意两点u和v都存在u到v或v到u的路径. 方法是,找出图中所有强连通分量,强连通分量上的点肯定也是满足单连通性的,然后对强连通分量进行缩点,缩点后就变 ...

  4. poj 2762 Going from u to v or from v to u?(强连通分量+缩点重构图+拓扑排序)

    http://poj.org/problem?id=2762 Going from u to v or from v to u? Time Limit: 2000MS   Memory Limit:  ...

  5. 【强连通分量缩点】poj 1236 Network of Schools

    poj.org/problem?id=1236 [题意] 给定一个有向图,求: (1)至少要选几个顶点,才能做到从这些顶点出发,可以到达全部顶点 (2)至少要加多少条边,才能使得从任何一个顶点出发,都 ...

  6. POJ 1236 Network Of Schools (强连通分量缩点求出度为0的和入度为0的分量个数)

    Network of Schools A number of schools are connected to a computer network. Agreements have been dev ...

  7. poj 2762 强连通缩点+拓扑排序

    这题搞了好久,先是拓扑排序这里没想到,一开始自己傻乎乎的跑去找每层出度为1的点,然后才想到能用拓扑排序来弄. 拓扑排序的时候也弄了挺久的,拓扑排序用的也不多. 题意:给一个图求是否从对于任意两个点能从 ...

  8. POJ 2762Going from u to v or from v to u?(强联通 + 缩点 + 拓扑排序)

    [题意]: 有N个房间,M条有向边,问能否毫无顾虑的随机选两个点x, y,使从①x到达y,或者,②从y到达x,一定至少有一条成立.注意是或者,不是且. [思路]: 先考虑,x->y或者y-> ...

  9. Going from u to v or from v to u?_POJ2762强连通+并查集缩点+拓扑排序

         Going from u to v or from v to u? Time Limit: 2000MS   Memory Limit: 65536K       Description I ...

随机推荐

  1. Akka的Actor模型及使用实例

    本文的绝大部分内容转载自rerun.me这一blog,老外写的东西就是好啊. ACTORS介绍 Anyone who has done multithreading in the past won't ...

  2. hdu 4614 Vases and Flowers(线段树:成段更新)

    线段树裸题.自己写复杂了,准确说是没想清楚就敲了. 先是建点为已插花之和,其实和未插花是一个道理,可是开始是小绕,后来滚雪球了,跪了. 重新建图,分解询问1为:找出真正插画的开始点和终止点,做成段更新 ...

  3. 任E行M1端口比特率特征码

    分辨率:800x480gps端口:com1比特率:4800设备特征码:01D1D008内存:128M

  4. Android 开发问题集合

    1.屏幕横.竖切换 修改“AndroidManifest.xml”的android:screenOrientation 一般需要:landscape.portrait 2.修改应用名字 修改“Andr ...

  5. Linux下通过ioctl系统调用来获取和设置网络信息

    #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h&g ...

  6. HDU 5879 Cure

    Cure Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  7. hdu 3461 Code Lock(并查集)2010 ACM-ICPC Multi-University Training Contest(3)

    想不到这还可以用并查集解,不过后来证明确实可以…… 题意也有些难理解—— 给你一个锁,这个所由n个字母组成,然后这个锁有m个区间,每次可以对一个区间进行操作,并且区间中的所有字母要同时操作.每次操作可 ...

  8. hdu 2544最短路——最短路的初次总结 UESTC 6th Programming Contest Online

    这是一道标准的模板题,所以拿来作为这一段时间学习最短路的总结题目. 题意很简单: 有多组输入数据,每组的第一行为两个整数n, m.表示共有n个节点,m条边. 接下来有m行,每行三个整数a, b, c. ...

  9. Bigger is Better

    题意: 有n个火柴棒,已知拼成9个数字花费的数目,求能拼出的能整除m的最大数 分析: dp[i][j]表示,用i个火柴棒,拼出的数余m余数为j时的最大数 int tmp=dp[i][j]*10+k;( ...

  10. e2e 自动化集成测试 架构 实例 WebStorm Node.js Mocha WebDriverIO Selenium Step by step (六) 自动化测试结构小节

    上一篇‘e2e 自动化集成测试 架构 京东 商品搜索 实例 WebStorm Node.js Mocha WebDriverIO Selenium Step by step (五) 如何让窗体记录登录 ...