zoukankan      html  css  js  c++  java
  • POJ 2553 The Bottom of a Graph

    The Bottom of a Graph

    Time Limit: 3000ms
    Memory Limit: 65536KB
    This problem will be judged on PKU. Original ID: 2553
    64-bit integer IO format: %lld      Java class name: Main
     
    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, epairs 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

     
    解题:求这样的点,它能到的点,那点也可以到它,注意先后顺序。然后求强联通缩点,出度为0的集合,里面的点即为我们求得那些点
     
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cmath>
     5 #include <algorithm>
     6 #include <climits>
     7 #include <vector>
     8 #include <queue>
     9 #include <cstdlib>
    10 #include <string>
    11 #include <set>
    12 #include <stack>
    13 #define LL long long
    14 #define pii pair<int,int>
    15 #define INF 0x3f3f3f3f
    16 using namespace std;
    17 const int maxn = 6000;
    18 struct arc {
    19     int to,next;
    20     arc(int x = 0,int y = -1) {
    21         to = x;
    22         next = y;
    23     }
    24 };
    25 arc e[maxn*100];
    26 int head[maxn],dfn[maxn],low[maxn],belong[maxn],my[maxn];
    27 int tot,n,m,top,scc,idx,out[maxn],ans[maxn];
    28 bool instack[maxn];
    29 void init() {
    30     for(int i = 0; i < maxn; ++i) {
    31         dfn[i] = low[i] = belong[i] = 0;
    32         instack[i] = false;
    33         head[i] = -1;
    34         out[i] = 0;
    35     }
    36     scc = tot = idx = top = 0;
    37 }
    38 void add(int u,int v){
    39     e[tot] = arc(v,head[u]);
    40     head[u] = tot++;
    41 }
    42 void tarjan(int u) {
    43     dfn[u] = low[u] = ++idx;
    44     my[top++] = u;
    45     instack[u] = true;
    46     for(int i = head[u]; ~i; i = e[i].next) {
    47         if(!dfn[e[i].to]) {
    48             tarjan(e[i].to);
    49             low[u] = min(low[u],low[e[i].to]);
    50         } else if(instack[e[i].to]) low[u] = min(low[u],dfn[e[i].to]);
    51     }
    52     if(dfn[u] == low[u]) {
    53         scc++;
    54         int v;
    55         do {
    56             v = my[--top];
    57             instack[v] = false;
    58             belong[v] = scc;
    59         } while(v != u);
    60     }
    61 }
    62 int main() {
    63     int u,v;
    64     while(~scanf("%d",&n)&&n) {
    65         scanf("%d",&m);
    66         init();
    67         for(int i = 0; i < m; ++i) {
    68             scanf("%d%d",&u,&v);
    69             add(u,v);
    70         }
    71         for(int i = 1; i <= n; ++i)
    72             if(!dfn[i]) tarjan(i);
    73         for(int i = 1; i <= n; ++i)
    74             for(int j = head[i]; ~j; j = e[j].next)
    75                 if(belong[i] != belong[e[j].to]) out[belong[i]]++;
    76         int cnt = 0;
    77         for(int i = 1; i <= n; ++i)
    78             if(!out[belong[i]]) ans[cnt++] = i;
    79         if(cnt){
    80             for(int i = 0; i < cnt; ++i)
    81                 printf("%d%c",ans[i],i + 1 == cnt?'
    ':' ');
    82         }else puts("");
    83     }
    84     return 0;
    85 }
    View Code
  • 相关阅读:
    WINREG.H 编译出错
    WINREG.H 编译出错
    JS创建对象的几种方式
    清除radio单选框外边距
    Dragging MovieClips
    Cannot Say No
    分层提高软件系统的可测试性
    如何从技术上掌控项目?
    领导我只需要你告诉我你要做什么,怎么做让我来好吗?
    如何依据框架进行任务分解
  • 原文地址:https://www.cnblogs.com/crackpotisback/p/4095991.html
Copyright © 2011-2022 走看看