1. //求这样的sink点:它能达到的点,那个点必能达到他,即(G)={v∈V|任意w∈V:(v→w)推出(w→v)}
  2. //我法:tarjan缩点后,遍历点,如果该点到达的点不在同一个强连通中,该点排除,而且该点所在的
  3. //的强连通分支所有点都排除(开始因为这个跪WA!慎思!)
  4. #include<iostream> //143MS,
  5. #include<vector>
  6. #include<cstdio>
  7. #include<cstring>
  8. #include<stack>
  9. #include<queue>
  10. using namespace std;
  11. int n;int m;
  12. const int MAX=5001;
  13. vector<vector<int> >edges(MAX);
  14. int visited[MAX];
  15. int low[MAX];
  16. int dfn[MAX];
  17. int is_sink[MAX]; //统计出入度
  18. int Strongly_connected_branch[MAX]; //并为一个强连通,标记为1.2.3...
  19. int num;int times;
  20. bool is_sink_all[MAX];
  21. stack<int>s;
  22. bool instack[MAX];
  23. void tarjan(int u)
  24. {
  25. low[u]=dfn[u]=times++;
  26. instack[u]=1;
  27. s.push(u);
  28. int len=edges[u].size();
  29. for(int i=0;i<len;i++)
  30. {
  31. int v=edges[u][i];
  32. if(visited[v]==0) //小心细节!
  33. {
  34. visited[v]=1;
  35. tarjan(v);
  36. if(low[u]>low[v])low[u]=low[v];
  37. }
  38. else if(instack[v]&&low[u]>dfn[v]) //有向图,要问是否在栈中,后向边,V为U某个祖先
  39. {
  40. low[u]=dfn[v];
  41. }
  42. }
  43. if(dfn[u]==low[u]) //在一个SCC
  44. {
  45. num++;int temp;
  46. do
  47. {
  48. temp=s.top();
  49. instack[temp]=0;
  50. s.pop();
  51. Strongly_connected_branch[temp]=num;
  52. } while(temp!=u);
  53. }
  54. }
  55. void initialize()
  56. {
  57. num=times=0;
  58. for(int i=0;i<=n;i++)
  59. {
  60. instack[i]=low[i]=dfn[i]=visited[i]=0;
  61. edges[i].clear();
  62. is_sink_all[i]=is_sink[i]=1;
  63. Strongly_connected_branch[i]=-1;
  64. }
  65. }
  66. bool readin()
  67. {
  68. scanf("%d",&n);
  69. if(n==0)return 0;
  70. scanf("%d",&m);
  71. initialize();
  72. int from,to;
  73. for(int i=1;i<=m;i++)
  74. {
  75. scanf("%d%d",&from,&to);
  76. edges[from].push_back(to);
  77. }
  78. return 1;
  79. }
  80. void solve()
  81. {
  82. for(int i=1;i<=n;i++)
  83. if(visited[i]==0)
  84. {
  85. visited[i]=1;
  86. tarjan(i);
  87. }
  88. for(int i=1;i<=n;i++) //自己思得:枚举所有边,缩点只是把所有SCC分开
  89. {
  90. int len=edges[i].size();
  91. for(int j=0;j<len;j++)
  92. {
  93. int v=edges[i][j];
  94. if(Strongly_connected_branch[v]!=Strongly_connected_branch[i])//b不再用一个强连通分支
  95. {
  96. is_sink[i]=0;
  97. is_sink_all[Strongly_connected_branch[i]]=0; //其所在强连通全跪!
  98. break;
  99. }
  100. }
  101. }
  102. queue<int>q; //要按顺序输出,无奈。
  103. for(int i=1;i<=n;i++)
  104. {
  105. if(is_sink_all[Strongly_connected_branch[i]]==0){continue;}
  106. if(is_sink[i]==1)q.push(i);
  107. }
  108. while(!q.empty())
  109. {
  110. int cur=q.front();
  111. if(q.size()==1)printf("%d\n",cur);
  112. else printf("%d ",cur);
  113. q.pop();
  114. }
  115. }
  116. int main() //代码越来越清楚O(∩_∩)O~
  117. {
  118. while(readin())
  119. {
  120. solve();
  121. }
  122. return 0;
  123. }

poj2553 有向图缩点,强连通分量。的更多相关文章

  1. Tarjan算法应用 (割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)问题)(转载)

    Tarjan算法应用 (割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)问题)(转载) 转载自:http://hi.baidu.com/lydrainbowcat/blog/item/2 ...

  2. Tarjan应用:求割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)【转】【修改】

    一.基本概念: 1.割点:若删掉某点后,原连通图分裂为多个子图,则称该点为割点. 2.割点集合:在一个无向连通图中,如果有一个顶点集合,删除这个顶点集合,以及这个集合中所有顶点相关联的边以后,原图变成 ...

  3. (转)Tarjan应用:求割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)

    基本概念: 1.割点:若删掉某点后,原连通图分裂为多个子图,则称该点为割点. 2.割点集合:在一个无向连通图中,如果有一个顶点集合,删除这个顶点集合,以及这个集合中所有顶点相关联的边以后,原图变成多个 ...

  4. tarjan算法-解决有向图中求强连通分量的利器

    小引 看到这个名词-tarjan,大家首先想到的肯定是又是一个以外国人名字命名的算法.说实话真的是很佩服那些算法大牛们,佩服得简直是五体投地啊.今天就遇到一道与求解有向图中强连通分量的问题,我的思路就 ...

  5. POJ2553( 有向图缩点)

    The Bottom of a Graph Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 9779   Accepted:  ...

  6. 『Tarjan算法 有向图的强连通分量』

    有向图的强连通分量 定义:在有向图\(G\)中,如果两个顶点\(v_i,v_j\)间\((v_i>v_j)\)有一条从\(v_i\)到\(v_j\)的有向路径,同时还有一条从\(v_j\)到\( ...

  7. Tarjan算法初探 (1):Tarjan如何求有向图的强连通分量

    在此大概讲一下初学Tarjan算法的领悟( QwQ) Tarjan算法 是图论的非常经典的算法 可以用来寻找有向图中的强连通分量 与此同时也可以通过寻找图中的强连通分量来进行缩点 首先给出强连通分量的 ...

  8. 【Luogu P3387】缩点模板(强连通分量Tarjan&拓扑排序)

    Luogu P3387 强连通分量的定义如下: 有向图强连通分量:在有向图G中,如果两个顶点vi,vj间(vi>vj)有一条从vi到vj的有向路径,同时还有一条从vj到vi的有向路径,则称两个顶 ...

  9. 图论-求有向图的强连通分量(Kosaraju算法)

    求有向图的强连通分量     Kosaraju算法可以求出有向图中的强连通分量个数,并且对分属于不同强连通分量的点进行标记. (1) 第一次对图G进行DFS遍历,并在遍历过程中,记录每一个点的退出顺序 ...

随机推荐

  1. Android利用Socket与硬件通信之智能家居APP

    前几天做一个智能家居APP,硬件段使用的是ESP8266WIFI模块,其实不管是WIFI模块还是蓝牙,通信都是同样一个道理,获取IP和端口来进行通信. 我是通过XCOM v2.0 发送信息,移动端接收 ...

  2. Ubuntu docker 使用命令 系列二

    1.下载官方远程仓下的镜像:sudo docker pull <docker 镜像> ,sudo docker pull centos (没有指定版本,就是下载的最新的os) 2. 下载某 ...

  3. DDR SDRAM

    DDR SDRAM(Double Data Rate SDRAM)是一种高速CMOS.动态随机访问存储器, 它采用双倍数据速率结构来完成高速操作.应用在高速信号处理系统中, 需要缓存高速.大量的数据的 ...

  4. EJB2的配置

    1. ejb-jar.xml <?xml version="1.0" encoding="UTF-8"?> <ejb-jar xmlns=&q ...

  5. 一个SAP开发人员的双截棍之路

    由于种种原因,Jerry最近加入了SAP成都研究院的一个演讲俱乐部,这个俱乐部主要是提高大家的英语演讲能力. 说来Jerry也是大一下期和大二上期一次性高分通过四六级考试的,但是当毕业进入SAP成都研 ...

  6. 微信小程序工具真机调试提示page "xxx/xxx/xxx" is not found

    解决方法: pages对象添加该页面

  7. 深入理解typeof操作符

    typeof可以检测数据的类型 typeof返回结果的其实是字符串:可以通过以下测试出来 console.log( typeof(typeof(a))); // string typeof返回的数据类 ...

  8. pyquery 基本使用笔记

    安装 pip install pyquery 导入 from pyquery import PyQuery as pq 初始化: from pyquery import PyQuery as pq h ...

  9. Poj 2337 Catenyms(有向图DFS求欧拉通路)

    题意: 给定n个单词, 问是否存在一条欧拉通路(如acm,matal,lack), 如果存在, 输出字典序最小的一条. 分析: 这题可以看作http://www.cnblogs.com/Jadon97 ...

  10. 洛谷2016 战略游戏 (0/1状态的普通树形Dp)

    题意: 给出一个树,覆盖树上某一个点的花费为w[i],求树上每一条边至少有一个点覆盖的最小花费. 细节: 1.一条边的两端可以均被覆盖,但是不能存在一条边的两端都不被覆盖. 2.可能存在 分析: 对于 ...