poj2553——The Bottom of a Graph(强连通分量)

来源:互联网 发布:男装批发软件 编辑:程序博客网 时间:2024/05/22 10:31

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

昨天错了一晚上,今天换个模板就过了。。。
题意是求所有的sink node,即互相有连接的点。图中第一个样例里,1、3互相连接,但2、3没有,所以答案是1和3,。所以根据定义就知道是要求强连通分量里出度为0的点,然后把这些点按顺序输出

#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>#define MAXN 5005using namespace std;struct Node{    int x,y,next;} edge[MAXN*MAXN];int dfn[MAXN],low[MAXN],vis[MAXN],s[MAXN],belong[MAXN],head[MAXN];int in[MAXN],out[MAXN]; //入度,出度int n,tot=0,ssum=0,ans=0,times=0,t=0,ans2;void init(){    memset(head,-1,sizeof(head));    memset(dfn,0,sizeof(dfn));    memset(vis,0,sizeof(vis));    memset(low,0,sizeof(low));    memset(belong,0,sizeof(belong));    memset(out,0,sizeof(out));    tot=ssum=0;}void add(int x,int y){    edge[++tot].x=x;    edge[tot].y=y;    edge[tot].next=head[x];    head[x]=tot;}void tarjan(int x){    int y,i;    times++;    t++;    dfn[x]=low[x]=times;    vis[x]=1;    s[t]=x;    for (i=head[x]; i; i=edge[i].next)    {        y=edge[i].y;        if (vis[y]==0)        {            tarjan(y);            low[x]=min(low[x],low[y]);        }        if (vis[y]==1)            low[x]=min(low[x],dfn[y]);    }    if (dfn[x]==low[x])    {        ssum++;        do        {            y=s[t--];            belong[y]=ssum;            vis[y]=2;        }        while (y!=x);    }}int main(){    int i,j;    while(cin >> n&&n)    {        init();        int v,u;        scanf("%d",&j);        while(j--)        {            scanf("%d%d",&u,&v);            add(u,v);        }        for (i=1; i<=n; i++)            if (vis[i]==0)                tarjan(i);        for (i=1; i<=tot; i++)            if (belong[edge[i].x]!=belong[edge[i].y])            {                out[belong[edge[i].x]]++;            }        for(i=1;i<=n;++i)            if(out[belong[i]]==0)            cout<<i<<" ";        cout<<endl;    }}
0 0