• 有向图的强连通分量


    两次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
  • 相关阅读:
    冰蝎,从入门到魔改
    红蓝对抗——加密Webshell“冰蝎”攻防
    DGA域名的今生前世:缘起、检测、与发展
    DNS隐藏隧道的使用
    DPI (Deep Packet Inspection) 深度包检测技术
    中国菜刀原理
    一句话木马和中国菜刀的结合拿webshell
    十大黑客工具之一——中国菜刀
    十大ATT&CK攻击技战术
    防守方新秘籍:MITRE 发布主动防御指导框架Shield
  • 原文地址:https://www.cnblogs.com/robin1998/p/6715813.html
Copyright © 2020-2023  润新知