zoukankan      html  css  js  c++  java
  • 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/
    新的风暴已经出现 怎么能够停止不前 穿越时空 竭尽全力 我会来到你身边 微笑面对危险 梦想成真不会遥远 鼓起勇气 坚定向前 奇迹一定会出现

     
  • 相关阅读:
    android 多线程
    Uva 10881 Piotr’s Ants 蚂蚁
    LA 3708 Graveyard 墓地雕塑 NEERC 2006
    UVa 11300 Spreading the Wealth 分金币
    UVa 11729 Commando War 突击战
    UVa 11292 The Dragon of Loowater 勇者斗恶龙
    HDU 4162 Shape Number
    HDU 1869 六度分离
    HDU 1041 Computer Transformation
    利用可变参数函数清空多个数组
  • 原文地址:https://www.cnblogs.com/whistle13326/p/6379320.html
Copyright © 2011-2022 走看看