题目链接: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. powerScript脚本

    一.powerScript的语法 1.0变量的命名及使用 powerscript的标识符(变量名称)必须以字母或下划线开头,其它的字符可以是下划线(_).短横线(-).美元符号($).号码符号(#) ...

  2. sql字符串函数(转)

    计算字符串长度 len()用来计算字符串的长度 select sname ,len(sname) from student 字符串转换为大.小写 lower() 用来将一个字符串转换为小写,upper ...

  3. QQ在线图标 离线 QQ开通在线QQ服务 QQ陌生人直接聊天

           如图  永远都显示离线,即使QQ在线也显示离线的原因和解决方法   1:打开 这个页面  提示你开通  你就点击一下开通  这样头像就可以正常显示 离线 和在线了 http://wp.q ...

  4. android-async-http

    安装 http://blog.csdn.net/wangwei_cq/article/details/9453345 包内的一些基本的参数 http://www.cnblogs.com/manuose ...

  5. 使用Java VisualVM监控远程JVM

    我们经常需要对我们的开发的软件做各种测试, 软件对系统资源的使用情况更是不可少, 目前有多个监控工具, 相比JProfiler对系统资源尤其是内存的消耗是非常庞大,JDK1.6开始自带的VisualV ...

  6. [Sciter系列] MFC下的Sciter–2.Sciter中的事件,tiscript,语法

    [Sciter系列] MFC下的Sciter–2.Sciter中的事件,tiscript,CSS部分自觉学习,重点说明Tiscript部分的常见语法和事件用法. 本系列文章的目的就是一步步构建出一个功 ...

  7. ti processor sdk linux am335x evm /bin/setup-uboot-env.sh hacking

    #!/bin/sh # # ti processor sdk linux am335x evm /bin/setup-uboot-env.sh hacking # 说明: # 本文主要对TI的sdk中 ...

  8. 【转】Linux Posix Timer使用

    原文网址:http://blog.csdn.net/hongszh/article/details/8608781 最强大的定时器接口来自POSIX时钟系列,其创建.初始化以及删除一个定时器的行动被分 ...

  9. TCP/IP详解学习笔记(14)-TCP连接的未来和性能(未写完)

    在TCP刚出世的时候,其主要工作环境是以太网和SLIP之类的低速网络.随着高速网络的出现,让TCP协议的吞吐量更大,效率更高的要求就愈来愈迫切.为此,TCP增加了三个重要机制来对应现在的变化,他们是 ...

  10. FileReader乱码

    出现原因:FileReader读取文件的过程中,FileReader继承了InputStreamReader,但并没有实现父类中带字符集参数的构造函数,所以FileReader只能按系统默认的字符集来 ...