POJ 2553 强联通缩点,找出度为0的点。

                                                                                       The Bottom of a Graph











Time Limit: 3000MSMemory Limit: 65536K
Total Submissions: 8019Accepted: 3313

 


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
题意:不解释。
思路:tarjin缩点,判断每个点所处连通分量出度是否为0,输出即可。
代码:
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<string>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<stack>
using namespace std;
const int maxn=5010;
int head[maxn],tol,low[maxn],dfn[maxn],Stack[maxn],instack[maxn],belong[maxn],out[maxn],indexx,scc,top;
struct node
{
        int to,next;
}edge[10*maxn];
void add(int u,int v)
{
        edge[tol].to=v;
        edge[tol].next=head[u];
        head[u]=tol++;
}
void tarjin(int u)
{
        low[u]=dfn[u]=++indexx;
        Stack[top++]=u;instack[u]=1;
        int i,v;
        for(i=head[u];i!=-1;i=edge[i].next)
        {
                v=edge[i].to;
                if(!dfn[v])
                {
                        tarjin(v);
                        if(low[u]>low[v])low[u]=low[v];
                }
                else if(instack[v]&&low[u]>dfn[v])low[u]=dfn[v];
        }
        if(low[u]==dfn[u])
        {
                scc++;
                do
                {
                        v=Stack[--top];
                        instack[v]=0;
                        belong[v]=scc;
                }while(u!=v);
        }
}
void solve(int n)
{
        memset(instack,0,sizeof(instack));
        memset(dfn,0,sizeof(dfn));
        memset(belong,0,sizeof(belong));
        scc=top=indexx=0;
        int i,u,v;
        for(i=1;i<=n;i++)if(!dfn[i])tarjin(i);
        //cout<<scc<<endl;
        
//for(i=1;i<=n;i++)cout<<belong[i]<<" ";cout<<endl;
        memset(out,0,sizeof(out));
        for(u=1;u<=n;u++)
        {
                for(i=head[u];i!=-1;i=edge[i].next)
                {
                        v=edge[i].to;
                        if(belong[u]!=belong[v])out[belong[u]]++;
                      //  printf("u=%d,v=%d,  %d %d\n",u,v,belong[u],belong[v]);
                }
        }
        vector<int> s;
        s.clear();
        for(i=1;i<=n;i++)
        {
               // cout<<out[belong[i]]<<" ";
                if(out[belong[i]]==0)s.push_back(i);
        }
       // cout<<endl;
       int len=s.size();
        if(len==0){puts("");return;}
        for(i=0;i<len;i++)
        {
                printf("%d",s[i]);
                if(i==len-1)puts("");
                else cout<<" ";
        }
}
int main()
{
        int i,j,k,m,n;
        while(~scanf("%d",&n)&&n)
        {
                scanf("%d",&m);
                memset(head,-1,sizeof(head));tol=0;
                while(m--)
                {
                        scanf("%d%d",&i,&j);
                        add(i,j);
                }
                solve(n);
        }
        return 0;
}
posted @ 2013-09-03 00:04  线性无关  阅读(155)  评论(0)    收藏  举报