• 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 }
  • 相关阅读:
    Java 添加OLE对象到Excel文档
    【51Nod1769】Clarke and math2(数论,组合数学)
    【UOJ#308】【UNR#2】UOJ拯救计划
    【UOJ#390】【UNR#3】百鸽笼(动态规划,容斥)
    【UOJ#389】【UNR#3】白鸽(欧拉回路,费用流)
    【UOJ#388】【UNR#3】配对树(线段树,dsu on tree)
    【UOJ#386】【UNR#3】鸽子固定器(贪心)
    【Wannafly挑战赛29F】最后之作(Trie树,动态规划,斜率优化)
    【洛谷5439】【XR-2】永恒(树链剖分,线段树)
    【洛谷5437】【XR-2】约定(拉格朗日插值)
  • 原文地址:https://www.cnblogs.com/DarkScoCu/p/10540137.html
Copyright © 2020-2023  润新知