zoukankan      html  css  js  c++  java
  • 有向图的强连通分量

    两次dfs模板:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define INF 0x3f3f3f3f
     4 #define M(a, b) memset(a, b, sizeof(a))
     5 const int N = 1000 + 5;
     6 int vis[N], sccno[N], scc_cnt;
     7 vector<int> G[N], G2[N];
     8 vector<int> S;
     9 
    10 void dfs1(int u) {
    11     if (vis[u]) return;
    12     vis[u] = 1;
    13     for (int i = 0; i < G[u].size(); ++i) dfs1(G[u][i]);
    14     S.push_back(u);
    15 }
    16 
    17 void dfs2(int u) {
    18     if (sccno[u]) return;
    19     sccno[u] = scc_cnt;
    20     for (int i = 0; i < G[u].size(); ++i) dfs2(G[u][i]);
    21 }
    22 
    23 void find_scc(int n) {
    24     M(vis, 0); M(sccno, 0);
    25     S.clear(); scc_cnt = 0;
    26     for (int i = 0; i < n; ++i) dfs1(i);
    27     for (int i = n-1; i >= 0; --i) 
    28         if (!sccno[i]) {++scc_cnt; dfs2(i);}
    29 }
    30 
    31 int main() {
    32     int n, m;
    33     while (cin >> n >> m) {
    34         int u, v;
    35         for (int i = 0; i < m; ++i) {
    36             cin >> u >> v;
    37             G[u].push_back(v);
    38             G2[v].push_back(u);
    39         }
    40         find_scc(n);        
    41     }
    42 
    43     return 0;
    44 }
    View Code

    Tarjan算法模板:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define M(a, b) memset(a, b, sizeof(a))
     4 #define INF 0x3f3f3f3f
     5 const int N = 1000 + 5;
     6 int pre[N], sccno[N], dfs_clock, scc_cnt;
     7 vector<int> G[N];
     8 stack<int> S;
     9 
    10 int dfs(int u) {
    11     int lowu = pre[u] = ++dfs_clock;
    12     S.push(u);
    13     for (int i = 0; i < G[u].size(); ++i) {
    14         int v = G[u][i];
    15         if (!pre[v]) {
    16             int lowv = dfs(v);
    17             lowu = min(lowu, lowv);
    18         }
    19         else if (!sccno[v]) { //加这个判定条件去掉已经包含在其他强连通分量中的反向边
    20             lowu = min(lowu, pre[v]);
    21         }
    22     }
    23     if (lowu == pre[u]) {
    24         ++scc_cnt;
    25         while (true) {
    26             int x = S.top(); S.pop();
    27             sccno[x] = scc_cnt;
    28             if (x == u) break;
    29         }
    30     }
    31     return lowu;
    32 }
    33 
    34 void find_scc(int n) {
    35     M(pre, 0); M(sccno, 0);
    36     dfs_clock = scc_cnt = 0;
    37     for (int i = 0; i < n; ++i) 
    38         if (!pre[i]) dfs(i); 
    39 }
    40 
    41 int main() {
    42     int n, m;
    43     while (cin >> n >> m) {
    44         int u, v;
    45         for (int i = 0; i < m; ++i) {
    46             cin >> u >> v;
    47             G[u].push_back(v);
    48         }
    49         find_scc(n);        
    50     }
    51 
    52     return 0;
    53 }
    View Code
  • 相关阅读:
    solrcloud
    nginx代理服务器3--高可用(keepalived)
    Nginx反向代理1--基本介绍-虚拟主机
    Nginx反向代理2--配置文件配置
    C/S与B/S区别
    数据类型转换(客户端与服务器端)
    SYN Cookie的原理和实现
    ubuntu 18.04 配置 rc.local
    Summary Checklist for Run-Time Kubernetes Security
    形意拳内功心法
  • 原文地址:https://www.cnblogs.com/robin1998/p/6715813.html
Copyright © 2011-2022 走看看