zoukankan      html  css  js  c++  java
  • 强连通分量 ZQUOJ 21467&&POJ 2553 The Bottom of a Graph

    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 x V, its elements being called edges. Then G=(V,E) is called a directed graph. 
    Let n be a positive integer, and let p=(e, ... , e) be a sequence of length n of edges ei  E such that ei = (vi ,vi+1 ) for a sequence of vertices ( v,... , 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 ( v 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 vv is also reachable from w. The bottom of a graph is the subset of all nodes that are sinks, i.e., bottom(G) = { vV | w∈V: (vw)  (wv) }. 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 v, w, ... , v, 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

    题目大意,给定一个有向图,按顺序输出“自己可达的顶点都可到达自己”的顶点。

    解题思路:先求出图的强连通分量,缩点,求出度为0的强连通分量中的顶点,并按按顺序输出。

    有关强强连通分量的算法请参考:http://www.byvoid.com/blog/scc-tarjan/(Tarjan算法)

                                              http://www.cnblogs.com/luweiseu/archive/2012/07/14/2591370.html(Tarjan,Kosaraju,Garbow)

                                              http://blog.csdn.net/liguanxing/article/details/5665520(Kosaraju算法)

                                              http://hi.baidu.com/yy17yy/item/8f4142dee291e6ee3cc2cb2f(Garbow算法)

     

    AC代码(Tarjan):

    View Code
     1 #include<stdio.h>
     2 #include<string.h>
     3 typedef struct
     4 {
     5     int v,next;
     6 }Node;
     7 Node e[50000];
     8 int n,m,index,top,count;
     9 int first[5001],DFN[5001],Low[5001],ver[5001];
    10 int belong[5001],stack[5001],instack[5001],val[5001],degree[5001];
    11 void Tarjan(int i)
    12 {
    13     int k,j,v;
    14     DFN[i]=Low[i]=index++;
    15     instack[i]=true;
    16     stack[top++]=i;
    17     for(j=first[i];j!=-1;j=e[j].next)
    18     {
    19         k=e[j].v;
    20         if(!DFN[k])
    21         {
    22             Tarjan(k);
    23             if(Low[k]<Low[i])
    24                 Low[i]=Low[k];
    25         }
    26         else if(instack[k]&&DFN[k]<Low[i])
    27             Low[i]=DFN[k];
    28     }
    29     if(Low[i]==DFN[i])
    30     {
    31         count++;
    32         do{
    33             v=stack[--top];
    34             instack[v]=false;
    35             belong[v]=count;
    36             val[count]++;
    37         }while(i!=v);
    38     }
    39 }
    40 int main()
    41 {
    42     int g,i,j,u,v;
    43     while(scanf("%d",&n)&&n)
    44     {
    45         scanf("%d",&m);
    46         g=0; index=0; top=0; count=0;
    47         memset(first,-1,sizeof(first));
    48         memset(DFN,0,sizeof(DFN));
    49         memset(Low,0,sizeof(Low));
    50         memset(degree,0,sizeof(degree));
    51         for(i=0;i<m;i++)
    52         {
    53             scanf("%d%d",&u,&v);
    54             e[g].v=v;
    55             e[g].next=first[u];
    56             first[u]=g++;
    57         }
    58         for(i=1;i<=n;i++)
    59             if(!DFN[i])
    60                 Tarjan(i);
    61         for(i=1;i<=n;i++)
    62             for(j=first[i];j!=-1;j=e[j].next)
    63             {
    64                 v=e[j].v;
    65                 if(belong[i]!=belong[v])
    66                     degree[belong[i]]++;
    67             }
    68         for(i=1;i<=n;i++)
    69         {
    70             if(!degree[belong[i]])
    71                 printf("%d ",i);
    72         }
    73         printf("\n");
    74     }
    75     return 0;
    76 }

    AC代码(Kosaraju):

    View Code
     1 #include<stdio.h>
     2 #include<string.h>
     3 typedef struct
     4 {
     5     int u,v,next1,next2;
     6 }Node;
     7 Node e[50000];
     8 int n,m,index;
     9 int first1[5001],first2[5001],vis[5001],belong[5001],num[5001],degree[5001];
    10 void dfs1(int i)
    11 {
    12     int j,k;
    13     vis[i]=1;
    14     for(j=first1[i];j!=-1;j=e[j].next1)
    15     {
    16         k=e[j].v;
    17         if(!vis[k])
    18             dfs1(k);
    19     }
    20     num[index++]=i;
    21 }
    22 void dfs2(int i)
    23 {
    24     int j,k;
    25     vis[i]=1;
    26     belong[i]=index;
    27     for(j=first2[i];j!=-1;j=e[j].next2)
    28     {
    29         k=e[j].u;
    30         if(!vis[k])
    31             dfs2(k);
    32     }
    33 }
    34 void kosaraju()
    35 {
    36     int i;
    37     index=1;
    38     memset(vis,0,sizeof(vis));
    39     for(i=1;i<=n;i++)
    40         if(!vis[i])
    41             dfs1(i);
    42     index=1;
    43     memset(vis,0,sizeof(vis));
    44     for(i=n;i>=1;i--)
    45         if(!vis[num[i]])
    46         {
    47             dfs2(num[i]);
    48             index++;
    49         }
    50 }
    51 int main()
    52 {
    53     int g,i,j,u,v;
    54     while(scanf("%d",&n)&&n)
    55     {
    56         g=0;
    57         memset(first1,-1,sizeof(first1));
    58         memset(first2,-1,sizeof(first2));
    59         memset(degree,0,sizeof(degree));
    60         scanf("%d",&m);
    61         for(i=1;i<=m;i++)
    62         {
    63             scanf("%d%d",&u,&v);
    64             e[g].v=v;
    65             e[g].next1=first1[u];
    66             first1[u]=g;
    67             e[g].u=u;
    68             e[g].next2=first2[v];
    69             first2[v]=g++;
    70         }
    71         kosaraju();
    72         for(i=1;i<=n;i++)
    73             for(j=first1[i];j!=-1;j=e[j].next1)
    74             {
    75                 v=e[j].v;
    76                 if(belong[i]!=belong[v])
    77                     degree[belong[i]]++;
    78             }
    79         for(i=1;i<=n;i++)
    80             if(!degree[belong[i]])
    81                 printf("%d ",i);
    82         printf("\n");
    83     }
    84     return 0;
    85 }

     AC代码(Garbow):

    View Code
     1 #include<stdio.h>
     2 #include<string.h>
     3 typedef struct
     4 {
     5     int v,next;
     6 }Node;
     7 Node e[50000];
     8 int n,m,index,top1,top2,count;
     9 int first[5001],low[5001],stack1[5001],stack2[5001];
    10 int belong[5001],degree[5001];
    11 void Garbow(int i)
    12 {
    13     int j,k;
    14     stack1[++top1]=stack2[++top2]=i;
    15     low[i]=index++;
    16     for(j=first[i];j!=-1;j=e[j].next)
    17     {
    18         k=e[j].v;
    19         if(!low[k])
    20             Garbow(k);
    21         else if(!belong[k])
    22         {
    23             while(low[stack2[top2]]>low[k])
    24                 top2--;
    25         }
    26     }
    27     if(stack2[top2]==i)
    28     {
    29         top2--;
    30         count++;
    31         do{
    32             k=stack1[top1--];
    33             belong[k]=count;
    34         }while(k!=i);
    35     }
    36 }
    37 int main()
    38 {
    39     int g,i,j,u,v;
    40     while(scanf("%d",&n)&&n)
    41     {
    42         scanf("%d",&m);
    43         g=0; top1=top2=-1; index=1; count=0;
    44         memset(first,-1,sizeof(first));
    45         memset(low,0,sizeof(low));
    46         memset(belong,0,sizeof(belong));
    47         memset(degree,0,sizeof(degree));
    48         for(i=1;i<=m;i++)
    49         {
    50             scanf("%d%d",&u,&v);
    51             e[g].v=v;
    52             e[g].next=first[u];
    53             first[u]=g++;
    54         }
    55         for(i=1;i<=n;i++)
    56             if(!low[i])
    57                 Garbow(i);
    58         for(i=1;i<=n;i++)
    59             for(j=first[i];j!=-1;j=e[j].next)
    60             {
    61                 v=e[j].v;
    62                 if(belong[i]!=belong[v])
    63                     degree[belong[i]]++;
    64             }
    65         for(i=1;i<=n;i++)
    66             if(!degree[belong[i]])
    67                 printf("%d ",i);
    68         printf("\n");
    69     }
    70     return 0;
    71 }

     

  • 相关阅读:
    Linux /dev/null详解
    Linux 重定向详解
    Linux history命令详解
    Linux echo命令详解
    Linux alias命令详解
    Linux fsck命令详解
    Linux blkid命令详解
    Linux mount命令详解
    Linux dd命令详解
    Linux free命令详解
  • 原文地址:https://www.cnblogs.com/frog112111/p/2626935.html
Copyright © 2011-2022 走看看