zoukankan      html  css  js  c++  java
  • The Bottom of a Graph(tarjan + 缩点)

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

    Description

    We will use the following (standard) definitions from graph theory. Let V be a nonempty and finite set, its elements being called vertices (or nodes). Let E be a subset of the Cartesian product V×V, its elements being called edges. Then G=(V,E) is called a directed graph. 
    Let n be a positive integer, and let p=(e1,...,en) be a sequence of length n of edges ei∈E such that ei=(vi,vi+1) for a sequence of vertices (v1,...,vn+1). Then p is called a path from vertex v1 to vertex vn+1in G and we say that vn+1 is reachable from v1, writing (v1→vn+1). 
    Here are some new definitions. A node v in a graph G=(V,E) is called a sink, if for every node w in G that is reachable from v, v is also reachable from w. The bottom of a graph is the subset of all nodes that are sinks, i.e., bottom(G)={v∈V|∀w∈V:(v→w)⇒(w→v)}. You have to calculate the bottom of certain graphs.

    Input

    The input contains several test cases, each of which corresponds to a directed graph G. Each test case starts with an integer number v, denoting the number of vertices of G=(V,E), where the vertices will be identified by the integer numbers in the set V={1,...,v}. You may assume that 1<=v<=5000. That is followed by a non-negative integer e and, thereafter, e pairs of vertex identifiers v1,w1,...,ve,we with the meaning that (vi,wi)∈E. There are no edges other than specified by these pairs. The last test case is followed by a zero.

    Output

    For each test case output the bottom of the specified graph on a single line. To this end, print the numbers of all nodes that are sinks in sorted order separated by a single space character. If the bottom is empty, print an empty line.

    Sample Input

    3 3
    1 3 2 3 3 1
    2 1
    1 2
    0
    

    Sample Output

    1 3
    2
    

    Source

    参考代码这里:http://blog.csdn.net/ehi11/article/details/7884851

    缩点:(这个概念也是看了别人的理解)先求有向图的强连通分量 , 如果几个点同属于一个强连通 , 那就给它们标上相同的记号 , 这样这几个点的集合就形成了一个缩点。

     题目大意:求出度为0的强连通分量

     1 #include<stdio.h>
     2 #include<queue>
     3 #include<string.h>
     4 using namespace std;
     5 const int M = 50010 ;
     6 int n , m ;
     7 int stack [M] , top = 0 , index = 0;
     8 bool instack [M] ;
     9 int dfn[M] , low[M] ;
    10 int cnt = 0 ;
    11 vector <int> e[M] ;
    12 int belong[M] ;
    13 int out[M] ;
    14 
    15 void init (int n)
    16 {
    17     top = 0 ;
    18     cnt = 0 ;
    19     index = 0 ;
    20     memset (stack , -1 , sizeof(stack)) ;
    21     memset (instack , 0 , sizeof(instack)) ;
    22     memset (dfn , -1 , sizeof(dfn)) ;
    23     memset (low , -1 , sizeof(low)) ;
    24     for (int i = 0 ; i <= n ; i++)
    25         e[i].clear () ;
    26     memset (belong , -1 , sizeof(belong)) ;
    27     memset (out , 0 , sizeof(out)) ;
    28 }
    29 
    30 void tarjan (int u)
    31 {
    32     int v ;
    33     dfn[u] = low[u] = index++ ;
    34     instack[u] = true ;
    35     stack[++top] = u ;
    36     for (int i = 0 ; i < e[u].size () ; i++) {
    37         v = e[u][i] ;
    38         if (dfn[v] == -1) {
    39             tarjan (v) ;
    40             low[u] = min (low[u] , low[v]) ;
    41         }
    42         else if (instack[v])
    43             low[u] = min (low[u] , dfn[v]) ;
    44     }
    45     if (low[u] == dfn[u]) {
    46         cnt++ ;
    47         do {
    48             v = stack[top--] ;
    49             instack[v] = false ;
    50             belong[v] = cnt ;
    51         } while (u != v) ;
    52     }
    53 }
    54 
    55 int main ()
    56 {
    57    //freopen ("a.txt" , "r" , stdin) ;
    58     int u , v ;
    59     while (~ scanf ("%d" ,&n)) {
    60         if (n == 0)
    61             break ;
    62         init (n) ;
    63         scanf ("%d" , &m) ;
    64         while (m--) {
    65             scanf ("%d%d" , &u , &v) ;
    66             e[u].push_back (v) ;
    67         }
    68         for (int i = 1 ; i <= n ; i++) {
    69             if (dfn[i] == -1)
    70                 tarjan (i) ;
    71         }
    72         for (int i = 1 ; i <= n ; i++) {
    73             for (int j = 0 ; j < e[i].size () ; j++) {
    74                 if (belong [i] != belong[e[i][j]])
    75                     out[belong[i]] ++;
    76             }
    77         }
    78         int k = 0 ;
    79         for (int i = 1 ; i <= n ; i++) {
    80             if (out[belong[i]] == 0) {
    81                 if (k++)
    82                     printf (" ") ;
    83                 printf ("%d" , i) ;
    84             }
    85         }
    86         puts ("") ;
    87     }
    88     return 0 ;
    89 }
    View Code
  • 相关阅读:
    【基础算法】- 全排列
    【基础算法】- 2分查找
    区块链培训
    Static Binding (Early Binding) vs Dynamic Binding (Late Binding)
    test
    No data is deployed on the contract address!
    "throw" is deprecated in favour of "revert()", "require()" and "assert()".
    Variable is declared as a storage pointer. Use an explicit "storage" keyword to silence this warning.
    京都行
    Failed to write genesis block: database already contains an incompatible
  • 原文地址:https://www.cnblogs.com/get-an-AC-everyday/p/4310720.html
Copyright © 2011-2022 走看看