POJ 2553 The Bottom of a Graph - from lanshui_Yang

原创 2013年08月17日 11:31:57

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 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
    题目大意:给你一个有向图,让你找出满足下面条件的点,并按序号从小到大输出。条件:对图中一个顶点V,对于图中每个能到达它的顶点w,w亦可到达v,当然,如果v不能到达其他顶点,这样的v也是满足条件的。
    解题思路:先用tarjan缩点,然后统计出出度为 0 的顶点即可。
    请看代码:
#include<iostream>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdio>
#include<queue>
#include<algorithm>
#include<set>
#include<vector>
#define mem(a , b) memset(a , b , sizeof(a))
using namespace std ;
const int MAXN = 5005 ;
vector<int> vert[MAXN] ;
vector<int> f[MAXN] ; // 统计每个强连通分量所包含的顶点
set<int> ans ;  // 记录满足条件的点,set 中的元素默认是从小到大排序的
int n , m ;
bool vis[MAXN] ;
int dfn[MAXN] ;
int low[MAXN] ;
int id[MAXN] ;  
int d[MAXN] ; // 统计每个强连通分量的出度
int stap[MAXN] ;
int top ;
bool inq[MAXN] ;
int tmpdfn ;
int fz ;
void clr()
{
    ans.clear() ;
    mem(vis , 0) ;
    mem(dfn , 0) ;
    mem(low , 0) ;
    mem(id , -1) ;
    mem(d , 0) ;
    mem(inq , 0) ;
    mem(stap , -1) ;
    tmpdfn = 0 ;
    top = -1 ;
    fz = 0 ;
    int i ;
    for(i = 1 ; i <= n ; i ++)
    {
        vert[i].clear() ;
        f[i].clear() ;
    }
}
void tarjan(int u)
{
    vis[u] = 1 ;
    stap[++ top] = u ;
    inq[u] = 1 ;
    dfn[u] = low[u] = ++ tmpdfn ;
    int i ;
    for(i = 0 ; i < vert[u].size() ; i ++)
    {
        int v = vert[u][i] ;
        if(!vis[v])
        {
            tarjan(v) ;
            low[u] = min(low[u] , low[v]) ;
        }
        else if(inq[v])
        {
            low[u] = min(low[u] , dfn[v]) ;
        }
    }
    if(low[u] == dfn[u])
    {
        fz ++ ;
        int tmp ;
        do
        {
            tmp = stap[top --] ;
            id[tmp] = fz ;
            f[fz].push_back(tmp) ;
            inq[tmp] = false ;
        }while (tmp != u) ;
    }
}
void init()
{
    clr() ;
    int i ;
    for(i = 0 ; i < m ; i ++)
    {
        int a , b ;
        scanf("%d%d" , &a , &b) ;
        vert[a].push_back(b) ;
    }
}
void solve()
{
    int i ;
    for(i = 1 ; i <= n ; i ++)
    {
        if(!vis[i])
        tarjan(i) ;
    }
    int j ;
    for(i = 1 ; i <= n ; i ++)
    {
        for(j = 0 ; j < vert[i].size() ; j ++)
        {
            int x , y ;
            x = id[i] ;
            y = id[ vert[i][j] ] ;
            if(x != y)
            {
                d[x] ++ ;
            }
        }
    }
    for(i = 1 ; i <= fz ; i ++)
    {
        if(d[i] == 0)
        {
            for(j = 0 ; j < f[i].size() ; j ++)
            {
                ans.insert(f[i][j]) ;
            }
        }
    }
    set<int> :: iterator it ;
    int sum = 0 ;
    for(it = ans.begin() ; it != ans.end() ; ++ it)
    {
        printf("%d" , *it) ;
        if(sum < ans.size() - 1)
        putchar(' ') ;
        sum ++ ;
    }
    puts("") ;
}
int main()
{
    while (scanf("%d" , &n) != EOF)
    {
        if(n == 0)
        break ;
        scanf("%d" , &m) ;
        init() ;
        solve() ;
    }
    return 0 ;
}


poj 2553 The Bottom of a Graph 【强连通图中出度为0点】

题目:poj 2553 The Bottom of a Graph  题意:大概题意是给出一个有向图,求强连通缩点以后出度为0的点。 分析:入门题目,先强连通缩点,然后表示出度为0...
  • y990041769
  • y990041769
  • 2014年11月04日 17:35
  • 923

POJ 2553 The Bottom of a Graph 缩点之后求出度为0的强联通分量的元素

点击打开链接 The Bottom of a Graph Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: ...
  • Dinivity123
  • Dinivity123
  • 2014年02月10日 22:38
  • 991

poj The Bottom of a Graph 2553 (强连通分量 找出汇点并输出汇点号)

The Bottom of a Graph Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 9429   Ac...
  • yanghui07216
  • yanghui07216
  • 2015年10月20日 20:56
  • 194

LeetCode -- Triangle 路径求最小和( 动态规划问题)

LeetCode Problem-- Triangle 路径求最小和 动态规划问题
  • mason_mow
  • mason_mow
  • 2014年05月25日 18:10
  • 1741

最长上升子序列练习 - from lanshui_Yang

POJ  3903 Stock Exchange :        此题也是简单的最长上升子序列问题,但由于数列长度n较大(n 代码如下: #include #include #include...
  • lanshui_Yang
  • lanshui_Yang
  • 2013年08月26日 16:27
  • 491

poj 2553 强连通

传送门 题意:找出出度为0的强连通分量,然后把这些强连通分量里的点按从小到大输出。 思路:求强连通分量,出度为0标记下,然后遍历点,看它所属的强连通分量是否被标记,如果是被标记的,记录点,然后排序...
  • cugbbaoge
  • cugbbaoge
  • 2013年08月03日 18:43
  • 492

POJ-1847-Tram(裸迪杰斯特拉或弗洛伊德)

R - 基础最短路 Time Limit:1000MS Memory Limit:30000KB 64bit IO Format:%I64d & %I64u SubmitStatu...
  • qq_32680617
  • qq_32680617
  • 2016年05月07日 10:44
  • 501

poj 2553 强连通

题意:给出一个有向图,定义:若节点v所有能到达的点{wi},都能反过来到达v,那么称节点v是sink。题目要求所有的sink点。   思路:强连通缩点找出出度为零的点,输出即可。   这题主要...
  • amourjun
  • amourjun
  • 2013年08月02日 16:08
  • 274

poj 1422 - 最小路径覆盖

题意:一个地图上有n个小镇,以及连接着其中两个小镇的有向边,而且这些边无法形成回路。现在选择一些小镇空降士兵(1个小镇最多1个士兵),士兵能沿着边走到尽头,问最少空降几个士兵,能遍历完所有的小镇。最小...
  • yujuan_Mao
  • yujuan_Mao
  • 2013年04月28日 23:52
  • 1305

Pattern(概述)

1 简介  Pattern的下载地址为:http://www.clips.ua.ac.be/pattern   Pattern是Python编程语言的一个Web挖掘模块。它具有数据挖掘工具(谷歌,...
  • qq280929090
  • qq280929090
  • 2017年04月27日 10:13
  • 566
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:POJ 2553 The Bottom of a Graph - from lanshui_Yang
举报原因:
原因补充:

(最多只允许输入30个字)