poj 2553 The Bottom of a Graph(强连通)

来源:互联网 发布:购买备案好的域名 编辑:程序博客网 时间:2024/04/27 21:53

题目链接

The Bottom of a Graph
Time Limit: 3000MS Memory Limit: 65536KTotal Submissions: 9003 Accepted: 3728

Description

We will use the following (standard) definitions from graph theory. LetV be a nonempty and finite set, its elements being called vertices (or nodes). LetE 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 lengthn 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 vertexv1 to vertex vn+1 in G and we say thatvn+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 nodew in G that is reachable from v, v is also reachable fromw. 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 graphG. Each test case starts with an integer number v, denoting the number of vertices ofG=(V,E), where the vertices will be identified by the integer numbers in the setV={1,...,v}. You may assume that 1<=v<=5000. That is followed by a non-negative integere 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 31 3 2 3 3 12 11 20

Sample Output

1 32

题意:给一个有向图,求出所有link点,若存在一条路径u->v,一定存在路径v->u,那么u则为link点。

题解:将强连通分量缩点,形成的新图一定是DAG,所以图中出度为0的强连通分量中的点一定为link点。代码如下:

#include<stdio.h>#include<iostream>#include<queue>#include<algorithm>#include<stack>#include<math.h>#include<vector>#include<string.h>#define nn 5500#define inff 0x3fffffffusing namespace std;int n,m;struct node{    int en,next;}E[nn*nn];int p[nn],num;void init(){    memset(p,-1,sizeof(p));    num=0;}void add(int st,int en){    E[num].en=en;    E[num].next=p[st];    p[st]=num++;}int dfn[nn],low[nn],df;int cnt;int fa[nn];bool insta[nn];stack<int>sta;void dfs(int id){    dfn[id]=low[id]=++df;    sta.push(id);    insta[id]=true;    int i,w;    for(i=p[id];i+1;i=E[i].next)    {        w=E[i].en;        if(dfn[w]==-1)        {            dfs(w);            low[id]=min(low[id],low[w]);        }        else if(insta[w])            low[id]=min(low[id],dfn[w]);    }    if(low[id]==dfn[id])    {        ++cnt;        int ix;        while(1)        {            ix=sta.top();            sta.pop();            insta[ix]=false;            fa[ix]=cnt;            if(ix==id)                break;        }    }}int cd[nn];vector<int>ans;void solve(){    memset(cd,0,sizeof(cd));    memset(insta,false,sizeof(insta));    memset(dfn,-1,sizeof(dfn));    df=cnt=0;    int i,j,w;    for(i=1;i<=n;i++)    {        if(dfn[i]==-1)        {            dfs(i);        }    }    for(i=1;i<=n;i++)    {        for(j=p[i];j+1;j=E[j].next)        {            w=E[j].en;            if(fa[i]!=fa[w])            {                cd[fa[i]]++;            }        }    }    for(i=1;i<=cnt;i++)    {        if(cd[i]==0)        {            for(j=1;j<=n;j++)            {                if(fa[j]==i)                {                    ans.push_back(j);                }            }        }    }}int main(){    int i;    while(scanf("%d",&n)&&n)    {        scanf("%d",&m);        int u,v;        init();        for(i=1;i<=m;i++)        {            scanf("%d%d",&u,&v);            add(u,v);        }        ans.clear();        solve();        sort(ans.begin(),ans.end());        for(i=0;i<(int)ans.size();i++)        {            printf("%d%c",ans[i],i==(ans.size()-1)?'\n':' ');        }        if(ans.empty())            puts("");    }    return 0;}


0 0
原创粉丝点击