zoukankan      html  css  js  c++  java
  • POJ 2553 The Bottom of a Graph(强连通分量)

     

    题目大意

     

    给你一个含有 n(1<=n<=5000) 个节点的有向图,判断图中哪些点事 sink

    sink 的定义:如果 u 是 sink,所有 u 能够到的点 v,v 也能到 u

     

    做法分析

     

    先缩点,形成的 DAG 中,那些出度为 0 的点就是答案

    证明如下(反证法):

            令 u 是 DAG 中的一个 sink

            假设 u 的出度不为 0,即在 DAG 中存在一个点 v,使得 u 能够到达 v。

            根据 sink 的定义:所有 u 能够到达的节点也能到达 u,那么 v 也能到达 u

            与 DAG 这一大前提矛盾

            故假设不成立,即 u 的出度为 0

    所以找出那些出度为 0 的强连通分量就是我们最终的答案

     

    参考代码

     

    POJ 2553
     1 #include <vector>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <cstdio>
     5 #include <stack>
     6 #include <iostream>
     7 
     8 using namespace std;
     9 
    10 const int N=5006;
    11 
    12 vector <int> arc[N], scc[N], ans;
    13 int n, m, ind, T;
    14 int dfn[N], low[N], id[N];
    15 bool vs[N];
    16 stack <int> s;
    17 
    18 void tarjan(int u)
    19 {
    20     s.push(u), vs[u]=1;
    21     dfn[u]=low[u]=T++;
    22     int len=(int)arc[u].size();
    23     for(int i=0; i<len; i++)
    24     {
    25         int v=arc[u][i];
    26         if(dfn[v]==-1)
    27         {
    28             tarjan(v);
    29             if(low[v]<low[u]) low[u]=low[v];
    30         }
    31         else if(vs[v] && low[u]>dfn[v]) low[u]=dfn[v];
    32     }
    33     if(low[u]==dfn[u])
    34     {
    35         for(int v; 1; )
    36         {
    37             v=s.top();
    38             s.pop(), vs[v]=0;
    39             id[v]=ind, scc[ind].push_back(v);
    40             if(v==u) break;
    41         }
    42         ind++;
    43     }
    44 }
    45 
    46 int main()
    47 {
    48     while(scanf("%d", &n), n!=0)
    49     {
    50         scanf("%d", &m);
    51         for(int i=1; i<=n; i++) arc[i].clear();
    52         for(int i=0, a, b; i<m; i++)
    53         {
    54             scanf("%d%d", &a, &b);
    55             arc[a].push_back(b);
    56         }
    57         for(int i=0; i<=n; i++) dfn[i]=-1, vs[i]=0, scc[i].clear();
    58         while(!s.empty()) s.pop();
    59         ind=T=0;
    60         for(int i=1; i<=n; i++) if(dfn[i]==-1) tarjan(i);
    61         for(int i=0; i<ind; i++) dfn[i]=0;
    62         for(int i=1; i<=n; i++)
    63         {
    64             int len=(int)arc[i].size(), u=id[i];
    65             for(int j=0; j<len; j++)
    66             {
    67                 int v=id[arc[i][j]];
    68                 if(v!=u) dfn[u]++;
    69             }
    70         }
    71         ans.clear();
    72         for(int i=0; i<ind; i++)
    73         {
    74             if(dfn[i]!=0) continue;
    75             int len=(int)scc[i].size();
    76             for(int j=0; j<len; j++) ans.push_back(scc[i][j]);
    77         }
    78         sort(ans.begin(), ans.end());
    79         int len=(int)ans.size();
    80         for(int i=0; i<len; i++)
    81         {
    82             printf("%d", ans[i]);
    83             if(i!=len-1) printf(" ");
    84         }
    85         printf("\n");
    86     }
    87     return 0;
    88 }

    AC通道

    POJ 2553 The Bottom of a Graph

  • 相关阅读:
    《机器学习》第二次作业——第四章学习记录和心得
    机器学习一到三章笔记
    [ML] 第四章学习总结
    [CV] Mnist手写数字分类
    ModelArts (华为GPU/CPU计算云平台)体验
    [DataSturcture] 红黑树求逆序对
    [CV] 边缘提取和角点判断
    [CV] 灰度共生矩阵
    [DataStructure] AC 自动机(Aho–Corasick Automata)
    [GIT] 如何删除git上保存的文件(包含历史文件)
  • 原文地址:https://www.cnblogs.com/zhj5chengfeng/p/2964010.html
Copyright © 2011-2022 走看看