zoukankan      html  css  js  c++  java
  • POJ 2553 The Bottom of a Graph Tarjan找环缩点(题解解释输入)

    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+1 in 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


    定义:点v是汇点须满足 --- 对图中任意点u,若v可以到达u则必有u到v的路径;若v不可以到达u,则u到v的路径可有可无。
    题意:在n个点m条边的有向图里面,问有多少个点是汇点。
    解释一下输入:分别是V顶点数,E边数,下一行每两个点是一条边的出入点。

    思路:很明显的Tarjan缩点,满足题意的汇点就是缩点以后出度为0的点。
     1 #include<cstdio>
     2 #include<algorithm>
     3 using namespace std;
     4 const int maxn = 5e3+5;
     5 int stack[maxn],dfn[maxn],low[maxn],head[maxn],dfs_num,top;
     6 int color[maxn],col_num,in[maxn],out[maxn],mm[maxn],a[maxn];
     7 bool vis[maxn];
     8 class edge
     9 {
    10 public:
    11     int to,next;
    12 }e[maxn*maxn];
    13 inline int gmin(int a,int b)
    14 {
    15     return a<b?a:b;
    16 }
    17 void Tarjan ( int x ) {
    18          dfn[ x ] = ++dfs_num ;
    19          low[ x ] = dfs_num ;
    20          vis [ x ] = true ;//是否在栈中
    21          stack [ ++top ] = x ;
    22          for ( int i=head[ x ] ; i!=0 ; i=e[i].next ){
    23                   int temp = e[ i ].to ;
    24                   if ( !dfn[ temp ] ){
    25                            Tarjan ( temp ) ;
    26                            low[ x ] = gmin ( low[ x ] , low[ temp ] ) ;
    27                  }
    28                  else if ( vis[ temp ])low[ x ] = gmin ( low[ x ] , dfn[ temp ] ) ;
    29          }
    30          if ( dfn[ x ]==low[ x ] ) {//构成强连通分量
    31                   vis[ x ] = false ;
    32                   color[ x ] = ++col_num ;//染色
    33                   while ( stack[ top ] != x ) {//清空
    34                            color [stack[ top ]] = col_num ;
    35                            vis [ stack[ top-- ] ] = false ;
    36                  }
    37                  top -- ;
    38          }
    39 }
    40 
    41 int main()
    42 {
    43     int n,m;
    44     while(scanf("%d",&n)){
    45     if(!n)break;
    46     scanf("%d",&m);
    47     col_num=dfs_num=top=0;
    48     for(int i=1;i<=n;i++)
    49         head[i]=in[i]=out[i]=dfn[i]=0;
    50     for(int i=1;i<=m;i++)
    51     {
    52         int x,y;
    53         scanf("%d%d",&x,&y);
    54         e[i].next=head[x];
    55         e[i].to=y;
    56         head[x]=i;
    57     }
    58     for(int i=1;i<=n;i++)if(!dfn[i])Tarjan(i);
    59     for(int i=1;i<=n;i++)
    60     {
    61         for(int j=head[i];j;j=e[j].next)
    62         {
    63             int t=e[j].to;
    64             if(color[i]!=color[t])
    65             {
    66                 out[color[i]]++;
    67                 in[color[t]]++;
    68             }
    69         }
    70     }
    71     int k=0,ans=0;
    72     for(int i=1;i<=col_num;i++)
    73         if(!out[i])mm[++k]=i;
    74     for(int i=1;i<=k;i++)
    75         for(int j=1;j<=n;j++)
    76         if(mm[i]==color[j])a[++ans]=j;
    77     sort(a+1,a+ans+1);
    78     //printf("%d %d %d
    ",k,ans,col_num);忘记初始化 debug多组样例一直过不了而加的..
    79     for(int i=1;i<=ans;i++)
    80         printf("%d%c",a[i],i!=ans?' ':'
    ');
    81     }
    82     return 0;
    83 }
    View Code
     
  • 相关阅读:
    平易近人、兼容并蓄——Spark SQL 1.3.0概览
    System.getProperty
    Apache Commons CLI 简介
    The declared package does not match the expected package
    Maven常用命令
    使用SBT构建Scala应用(转自git)
    Area Under roc Curve(AUC)
    用特征来实现混入(mix-in)式的多重继承
    暗时间
    SVN如何commit(提交)项目代码
  • 原文地址:https://www.cnblogs.com/llllrj/p/9405932.html
Copyright © 2011-2022 走看看