• 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×V, its elements being called edges. ThenG=(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+1is 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 vv 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

     
    题目大意 : 给你一个图,其中有两点u,v如果u能到达v,v也能到达u,那么这种点称为sink,输出所有sink 
     
    思路:u可以到达v,v可以到达u,明显是强连通分量,我们可以用tarjan来求。找到所有出度为0的强连通分量输出
     
    #include<stack>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #define MAXN 500005
    using namespace std;
    int head[MAXN],tot,sum,n,m;
    int dfn[MAXN],low[MAXN],belong[MAXN],cnt,f[MAXN];
    bool vis[MAXN];
    struct node {
        int to;
        int next;
    };
    node e[MAXN];
    stack<int> s;
    inline void read(int&x) {
        x=0;int f=1;char c=getchar();
        while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();}
        while(c>='0'&&c<='9') {x=(x<<1)+(x<<3)+c-48;c=getchar();}
        x=x*f;
    }
    inline void MEM() {
        memset(head,0,sizeof head);
        memset(dfn,0,sizeof dfn);
        memset(low,0,sizeof low);
        for(int i=1;i<=n;i++) {
            vis[i]=false;belong[i]=0;f[i]=false;
        }
        sum=0;
    }
    inline void add(int x,int y) {
        e[++tot].to=y;
        e[tot].next=head[x];
        head[x]=tot;
    }
    inline void tarjan(int u) {
        dfn[u]=low[u]=++cnt;
        vis[u]=true;s.push(u);
        for(int i=head[u];i;i=e[i].next) {
            int v=e[i].to;
            if(!dfn[v]) {
                tarjan(v);
                low[u]=min(low[u],low[v]);
            }
            else if(vis[v]) low[u]=min(low[u],dfn[v]);
        }
        if(dfn[u]==low[u]) {
            sum++;
            int t;
            do {
                t=s.top();
                s.pop();
                belong[t]=sum;
    
            }while(u!=t);
        }
    }
    int main() {
        int x,y;
        while(scanf("%d",&n)&&n) {
            read(m);
            MEM();cnt=0;tot=0;
            for(int i=1;i<=m;i++) {
                read(x);read(y);
                add(x,y);
            }
            for(int i=1;i<=n;i++)
              if(!dfn[i])
                tarjan(i);
            for(int i=1;i<=n;i++) {
                for(int j=head[i];j;j=e[j].next)
                  if(belong[e[j].to]!=belong[i]) {
                      f[belong[i]]=true;
                      break;
                  }
            }
            for(int i=1;i<=n;i++)
              if(!f[belong[i]]) printf("%d ",i);
            printf("
    ");
            while(!s.empty()) s.pop();
        }
        return 0;
    }
    View Code


    作者:乌鸦坐飞机
    出处:http://www.cnblogs.com/whistle13326/
    新的风暴已经出现 怎么能够停止不前 穿越时空 竭尽全力 我会来到你身边 微笑面对危险 梦想成真不会遥远 鼓起勇气 坚定向前 奇迹一定会出现

     
  • 相关阅读:
    js学习---常用的内置对象(API)小结 :
    js第四天学习小结:
    学习js第三天小结
    学习js第二天小结
    tomcat+redis会话共享
    linux文件归档脚本
    服务器群秒级别文件同步(ssh+SHELL)
    elasticsearch的索引自动清理及自定义清理
    ELK安装配置
    Logstash自带正则表达式
  • 原文地址:https://www.cnblogs.com/whistle13326/p/6379320.html
Copyright © 2020-2023  润新知