Write a program to find the strongly connected components in a digraph.

Format of functions:

  1. void StronglyConnectedComponents( Graph G, void (*visit)(Vertex V) );

where Graph is defined as the following:

  1. typedef struct VNode *PtrToVNode;
  2. struct VNode {
  3. Vertex Vert;
  4. PtrToVNode Next;
  5. };
  6. typedef struct GNode *Graph;
  7. struct GNode {
  8. int NumOfVertices;
  9. int NumOfEdges;
  10. PtrToVNode *Array;
  11. };

Here void (*visit)(Vertex V) is a function parameter that is passed into StronglyConnectedComponents to handle (print with a certain format) each vertex that is visited. The function StronglyConnectedComponents is supposed to print a return after each component is found.

Sample program of judge:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #define MaxVertices 10 /* maximum number of vertices */
  4. typedef int Vertex; /* vertices are numbered from 0 to MaxVertices-1 */
  5. typedef struct VNode *PtrToVNode;
  6. struct VNode {
  7. Vertex Vert;
  8. PtrToVNode Next;
  9. };
  10. typedef struct GNode *Graph;
  11. struct GNode {
  12. int NumOfVertices;
  13. int NumOfEdges;
  14. PtrToVNode *Array;
  15. };
  16. Graph ReadG(); /* details omitted */
  17. void PrintV( Vertex V )
  18. {
  19. printf("%d ", V);
  20. }
  21. void StronglyConnectedComponents( Graph G, void (*visit)(Vertex V) );
  22. int main()
  23. {
  24. Graph G = ReadG();
  25. StronglyConnectedComponents( G, PrintV );
  26. return 0;
  27. }
  28. /* Your function will be put here */

Sample Input (for the graph shown in the figure):

  1. 4 5
  2. 0 1
  3. 1 2
  4. 2 0
  5. 3 1
  6. 3 2

Sample Output:

  1. 3
  2. 1 2 0

Note: The output order does not matter. That is, a solution like

  1. 0 1 2
  2. 3

is also considered correct.

这题目就是直接照搬Tarjan算法实现就好了,Tarjan算法在《算法导论》上第22章有,但是我看了以后并没有明白Tarjan算法的过程orz,最后还是看blog看懂的,所以推荐一个讲Tarjan算法讲的很好的blog:http://blog.csdn.net/acmmmm/article/details/16361033 还有Tarjan算法实现的具体代码:http://blog.csdn.net/acmmmm/article/details/9963693 都是一个ACM大佬写的,我就是看这两个的……其实我也看了很久才看懂Tarjan算法是干啥的……毕竟上课从来不听不知道老师讲的方法是怎么样的……

当然只要理解了Tarjan算法,这题目就相当easy了。

补充:还看到一个英文的讲Tarjan的地方,讲的很全面,在geeksforgeeks上http://www.geeksforgeeks.org/tarjan-algorithm-find-strongly-connected-components/

就是打开可能会有点慢,但是不需要FQ。

直接放代码吧:

  1. //
  2. // main.c
  3. // Strongly Connected Components
  4. //
  5. // Created by 余南龙 on 2016/12/6.
  6. // Copyright © 2016年 余南龙. All rights reserved.
  7. //
  8.  
  9. int dfn[MaxVertices], low[MaxVertices], stack[MaxVertices], top, t, in_stack[MaxVertices];
  10.  
  11. int min(int a, int b){
  12. if(a < b){
  13. return a;
  14. }
  15. else{
  16. return b;
  17. }
  18. }
  19.  
  20. void Tarjan(Graph G, int v){
  21. PtrToVNode node = G->Array[v];
  22. int son, tmp;
  23.  
  24. dfn[v] = low[v] = ++t;
  25. stack[++top] = v;
  26. in_stack[v] = ;
  27.  
  28. while(NULL != node){
  29. son = node->Vert;
  30. == dfn[son]){
  31. Tarjan(G, son);
  32. low[v] = min(low[son], low[v]);
  33. }
  34. == in_stack[son]){
  35. low[v] = min(low[v], dfn[son]);
  36. }
  37. node = node->Next;
  38. }
  39. if(dfn[v] == low[v]){
  40. do{
  41. tmp = stack[top--];
  42. printf("%d ", tmp);
  43. in_stack[tmp] = ;
  44. }while(tmp != v);
  45. printf("\n");
  46. }
  47. }
  48.  
  49. void StronglyConnectedComponents( Graph G, void (*visit)(Vertex V) ){
  50. int i;
  51.  
  52. ; i < MaxVertices; i++){
  53. dfn[i] = -;
  54. low[i] = in_stack[i] = ;
  55. }
  56. top = -;
  57. t = ;
  58.  
  59. ; i < G->NumOfVertices; i++){
  60. == dfn[i]){
  61. Tarjan(G, i);
  62. }
  63. }
  64. }

PTA Strongly Connected Components的更多相关文章

  1. Strongly connected components

    拓扑排列可以指明除了循环以外的所有指向,当反过来还有路可以走的话,说明有刚刚没算的循环路线,所以反过来能形成的所有树都是循环

  2. algorithm@ Strongly Connected Component

    Strongly Connected Components A directed graph is strongly connected if there is a path between all ...

  3. [LeetCode] Number of Connected Components in an Undirected Graph 无向图中的连通区域的个数

    Given n nodes labeled from 0 to n - 1 and a list of undirected edges (each edge is a pair of nodes), ...

  4. LeetCode Number of Connected Components in an Undirected Graph

    原题链接在这里:https://leetcode.com/problems/number-of-connected-components-in-an-undirected-graph/ 题目: Giv ...

  5. [Redux] Using withRouter() to Inject the Params into Connected Components

    We will learn how to use withRouter() to inject params provided by React Router into connected compo ...

  6. [Locked] Number of Connected Components in an Undirected Graph

    Number of Connected Components in an Undirected Graph Given n nodes labeled from 0 to n - 1 and a li ...

  7. cf475B Strongly Connected City

    B. Strongly Connected City time limit per test 2 seconds memory limit per test 256 megabytes input s ...

  8. Strongly connected(hdu4635(强连通分量))

    /* http://acm.hdu.edu.cn/showproblem.php?pid=4635 Strongly connected Time Limit: 2000/1000 MS (Java/ ...

  9. [Swift]LeetCode323. 无向图中的连通区域的个数 $ Number of Connected Components in an Undirected Graph

    Given n nodes labeled from 0 to n - 1 and a list of undirected edges (each edge is a pair of nodes), ...

随机推荐

  1. Ice分布式程序设计—IceBox(Hello World Application)

    忙了三天,总算浏览完此书.藉此记下 Ice 的 IceBox 服务框架. 在此用 IceBox 框架写 Hello World 程序,即以载体来体现其特性. 第一步:编写 Slice 文件,映射生成 ...

  2. 【转】Hibernate级联注解CascadeType参数详解

    cascade(级联) 级联在编写触发器时经常用到,触发器的作用是当 主控表信息改变时,用来保证其关联表中数据同步更新.若对触发器来修改或删除关联表相记录,必须要删除对应的关联表信息,否则,会存有脏数 ...

  3. Socket网络编程-基础篇

    Socket网络编程 网络通讯三要素: IP地址[主机名] 网络中设备的标识 本地回环地址:127.0.0.1 主机名:localhost 端口号 用于标识进程的逻辑地址 有效端口:0~65535 其 ...

  4. Oracle数据库监听服务无法启动

    (1) 安装好Oracle后,启动Net Manager,测试orcl失败,报错“ORA-12514: TNS: 监听程序当前无法识别连接描述符中请求的服务”,需要修改监听文件.修改前: # list ...

  5. C# 多线程线程池( 一 )

    我们将在这里进一步讨论一些.NET类,以及他们在多线程编程中扮演的角色和怎么编程.它们是: System.Threading.ThreadPool 类 System.Threading.Timer 类 ...

  6. Android 软引用

    2013-08-13 13:56 佚名 eoe Android开发者社区 字号:T | T   可能对于Android开发者来说,软引用这个词有的会不是很熟悉,软引用在Java开发中用的比较多,但是, ...

  7. cmd执行mysql操作

    (以下已安装到本机的mysql为例) 登录mysql数据库,如果没有在环境变量配置path到mysql中的bin目录,需要手动进入该目录中 执行:mysql -u用户名 -p密码 (注意:只要进入了m ...

  8. Request与session与application的区别

    (1)request的setAttribute与getAttribute方法一般都是成对出现的,首先通过setAttribute方法设置属性与属性值,然后通过getAttribute方法根据属性获取到 ...

  9. Git--分布式版本控制系统

    使用Git实现多人协作开发 1.简述 每创建一个大的web项目都会有团队协作完成, 然这个过程有可能就像毕业生写论文的过程, 这个过程会有很多...修改的版本, 我们的项目也是会经过无休止的改需求, ...

  10. ---Linux 10 年的硕果累累啊!

    http://mt.sohu.com/20160128/n436204298.shtml