• 无向图的双连通分量


    点双连通分量模板(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], bccno[N], iscut[N], dfs_clock, bcc_cnt;
     7 vector<int> G[N], bcc[N]; 
     8 struct Edge {
     9     int u, v;
    10 };
    11 stack<Edge> S;
    12 
    13 int dfs(int u, int fa) {
    14     int lowu = pre[u] = ++dfs_clock;
    15     int child = 0;
    16     for (int i = 0; i < G[u].size(); ++i) {
    17         int v = G[u][i];
    18         if (v == fa) continue;
    19         Edge now = (Edge){u, v};
    20         if (!pre[v]) {
    21             S.push(now);
    22             ++child;
    23             int lowv = dfs(v, u);
    24             lowu = min(lowu, lowv);
    25             if (lowv >= pre[u]) {
    26                 iscut[v] = true;
    27                 ++bcc_cnt; bcc[bcc_cnt].clear();
    28                 while (1) {
    29                     Edge e = S.top(); S.pop();
    30                     if (bccno[e.u] != bcc_cnt) {bcc[bcc_cnt].push_back(e.u); bccno[e.u] = bcc_cnt;}
    31                     if (bccno[e.v] != bcc_cnt) {bcc[bcc_cnt].push_back(e.v); bccno[e.v] = bcc_cnt;}
    32                     if (e.u == u && e.v == v) break;
    33                 }
    34             }
    35         }
    36         else if (pre[v] < pre[u]) {
    37             S.push(now);
    38             lowu = min(lowu, pre[v]);
    39         }
    40     }
    41     if (fa < 0 && child == 1) iscut[u] = 0;
    42     return lowu;
    43 }
    44 
    45 void find_bcc(int n) {
    46     M(pre, 0); M(iscut, 0); M(bccno, 0);
    47     for (int i = 0; i < n; ++i)
    48         if (!pre[i]) dfs(i, -1);
    49 }
    50 
    51 int main() {
    52     int n, m, u, v;
    53     cin >> n >> m;
    54     for (int i = 0; i < m; ++i) {
    55         cin >> u >> v;
    56         u--; v--;
    57         G[u].push_back(v);
    58         G[v].push_back(u);
    59     }
    60     find_bcc(n);
    61     for (int i = 1; i <= bcc_cnt; ++i) {
    62         for (int j = 0; j < bcc[i].size(); ++j)
    63             cout << bcc[i][j]+1 << " ";
    64         cout << endl;
    65     }
    66 
    67     return 0;
    68 }
    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], bccno[N], dfs_clock, bcc_cnt;
     7 vector<int> G[N];
     8 
     9 stack<int> S;
    10 int dfs(int u, int fa) {
    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 (v == fa) continue;
    16         if (!pre[v]) {
    17             int lowv = dfs(v, u);
    18             lowu = min(lowu, lowv);
    19         }
    20         else lowu = min(lowu, pre[v]);
    21     }
    22     if (lowu == pre[u]) {
    23         ++bcc_cnt;
    24         while (1) {
    25             int k = S.top(); S.pop();
    26             bccno[k] = bcc_cnt;
    27             if (k == u) break; 
    28         }
    29     }
    30     return lowu;
    31 }
    32 
    33 void find_bcc(int n) {
    34     M(pre, 0); M(bccno, 0); dfs_clock = bcc_cnt = 0;
    35     for (int i = 0; i < n; ++i)
    36         if (!pre[i]) dfs(i, -1);
    37 }
    38 
    39 
    40 int main() {
    41     int n, m, u, v;
    42     cin >> n >> m;
    43     for (int i = 0; i < m; ++i) {
    44         cin >> u >> v;
    45         u--; v--;
    46         G[u].push_back(v);
    47         G[v].push_back(u);
    48     }
    49     find_bcc(n);
    50 
    51     return 0;
    52 }
    View Code
  • 相关阅读:
    Go实现线程池
    Go语言工程结构
    Go语言示例-函数返回多个值
    Go语言参数中的三个点是干什么的
    go语言示例-Timer计时器的用法
    Go语言的类型转化
    iOS 修改通讯录联系人地址(address)崩溃原因分析
    tableview小结-初学者的问题
    Objective-C总Runtime的那点事儿(一)消息机制
    论坛源码推荐(11.6):iPhone6/6 plus屏幕适配Demo,Java代码转Objective-C
  • 原文地址:https://www.cnblogs.com/robin1998/p/6706323.html
Copyright © 2020-2023  润新知