zoukankan      html  css  js  c++  java
  • poj 2553 The Bottom of a Graph : tarjan O(n) 存环中的点

      1 /**
      2 problem: http://poj.org/problem?id=2553
      3 将所有出度为0环中的点排序输出即可。
      4 **/
      5 
      6 #include<stdio.h>
      7 #include<stack>
      8 #include<vector>
      9 #include<algorithm>
     10 using namespace std;
     11 
     12 class Graphics{
     13     const static int MAXN = 5005;
     14     const static int MAXM = MAXN * MAXN;
     15 private:
     16     struct Edge{
     17         int to, next;
     18     }edge[MAXM];
     19     struct Point{
     20         int dfn, low, color;
     21         Point(){dfn = low = color = 0;}
     22     }point[MAXN], emptyPoint;
     23     int first[MAXN], sign, colorNum, dfnNum, sumOfPoint;
     24     bool vis[MAXN];
     25     vector<int> ring[MAXN];
     26     stack<int> stk;
     27     void tarjan(int u){
     28         point[u].dfn = ++ dfnNum;
     29         point[u].low = dfnNum;
     30         vis[u] = true;
     31         stk.push(u);
     32         for(int i = first[u]; i != -1; i = edge[i].next){
     33             int to = edge[i].to;
     34             if(!point[to].dfn){
     35                 tarjan(to);
     36                 point[u].low = min(point[to].low, point[u].low);
     37             }else if(vis[to]){
     38                 point[u].low = min(point[to].dfn, point[u].low);
     39             }
     40         }
     41         if(point[u].low == point[u].dfn){
     42             vis[u] = false;
     43             point[u].color = ++colorNum;
     44             ring[colorNum].push_back(u);
     45             while(stk.top() != u){
     46                 vis[stk.top()] = false;
     47                 point[stk.top()].color = colorNum;
     48                 ring[colorNum].push_back(stk.top());
     49                 stk.pop();
     50             }
     51             stk.pop();
     52         }
     53     }
     54 public:
     55     void clear(int n){
     56         sign = colorNum = dfnNum = 0;
     57         sumOfPoint = n;
     58         for(int i = 1; i <= n; i ++){
     59             first[i] = -1;
     60             vis[i] = false;
     61             ring[i].clear();
     62             point[i] = emptyPoint;
     63         }
     64         while(!stk.empty()) stk.pop();
     65     }
     66     void addEdgeOneWay(int u, int v){
     67         edge[sign].to = v;
     68         edge[sign].next = first[u];
     69         first[u] = sign ++;
     70     }
     71     void tarjanAllPoint(){
     72         for(int i = 1; i <= sumOfPoint; i ++){
     73             if(!point[i].dfn){
     74                 tarjan(i);
     75             }
     76         }
     77     }
     78     vector<int> getAns(){
     79         vector<int> ans;
     80         int *outdegree = new int[sumOfPoint+1];
     81         for(int i = 1; i <= sumOfPoint; i ++){
     82             outdegree[i] = 0;
     83         }
     84         tarjanAllPoint();
     85         for(int i = 1; i <= sumOfPoint; i ++){
     86             for(int j = first[i]; j != -1; j = edge[j].next){
     87                 int to = edge[j].to;
     88                 if(point[to].color != point[i].color){
     89                     outdegree[point[i].color] ++;
     90                 }
     91             }
     92         }
     93         for(int i = 1; i <= colorNum; i ++){
     94             if(!outdegree[i]){
     95                 for(int j = 0; j < ring[i].size(); j ++){
     96                     ans.push_back(ring[i][j]);
     97                 }
     98             }
     99         }
    100         sort(ans.begin(), ans.end());
    101         delete []outdegree;
    102         return ans;
    103     }
    104 }graph;
    105 
    106 int main(){
    107     int n, m;
    108     while(scanf("%d%d", &n, &m) != EOF && n){
    109         graph.clear(n);
    110         while(m --){
    111             int a, b;
    112             scanf("%d%d", &a, &b);
    113             graph.addEdgeOneWay(a, b);
    114         }
    115         vector<int> ans = graph.getAns();
    116         bool first = 1;
    117         for(int i = 0; i < ans.size(); i ++){
    118             if(first) first = 0;
    119             else putchar(' ');
    120             printf("%d", ans[i]);
    121         }
    122         putchar('
    ');
    123     }
    124     return 0;
    125 }
  • 相关阅读:
    转自一位前辈的杂谈
    在vim编辑器中实现python的tab补全
    Go语言 异常panic和恢复recover用法
    go语言的cron包的简单使用
    go语言的指针
    Python 报 OpenSSL.SSL.SysCallError: (10054, 'WSAECONNRESET')
    python 之图像处理
    git 线上连接及版本控制
    vue依赖pycharm启动
    模拟django 后台管理
  • 原文地址:https://www.cnblogs.com/DarkScoCu/p/10540137.html
Copyright © 2011-2022 走看看