zoukankan      html  css  js  c++  java
  • Tarjan 割点,桥

    /*         ggg   ggg
            ggggggg ggggggg
          ggggggggggggggggggg
            ggggggggggggggg
              ggggggggggg
                ggggggg
                  ggg
                   g
    */
    /*  gyt
           Live up to every day            */
    
    #include<cstdio>
    #include<cmath>
    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<stack>
    #include<cstring>
    #include<queue>
    #include<set>
    #include<string>
    #include<map>
    #include <time.h>
    #define PI acos(-1)
    using namespace std;
    typedef long long ll;
    typedef double db;
    const int maxn = 500+5;
    const ll maxm = 1e7;
    const int mod = 1e9 + 7;
    const int INF = 0x3f3f3f;
    const ll inf = 1e15 + 5;
    const db eps = 1e-9;
    #define N 201
    vector<int>G[N];
    int n,m,low[N],dfn[N];
    bool is_cut[N];
    int father[N];
    int tim=0;
    
    void init() {
        memset(dfn, -1, sizeof(dfn));
        memset(father, 0, sizeof(father));
        memset(low, -1, sizeof(low));
        memset(is_cut, 0, sizeof(is_cut));
    }
    void Tarjan(int i, int Father) {
        father[i] = Father;
        dfn[i] = low[i] = tim++;
        for (int j = 0; j < G[i].size(); j++) {
            int k = G[i][j];
            if (dfn[k]==-1) {
                Tarjan(k, i);
                low[i] = min(low[i], low[k]);
            }
            else if(Father != k) {
                low[i] = min(low[i], dfn[k]);
            }
        }
    }
    void cnt() {
        int rootson=0;
        Tarjan(1, 0);
        for(int i=2;i<=n;++i){
            int v=father[i];
            if(v==1)
            rootson++;/*统计根节点子树的个数,根节点的子树个数>=2,就是割点*/
            else{
                if(low[i]>=dfn[v])/*割点的条件*/
                is_cut[v]=true;
            }
        }
        if(rootson>1)
            is_cut[1]=true;
        for(int i=1;i<=n;++i)
            if(is_cut[i])
                printf("%d
    ",i);
        for(int i=1;i<=n;++i){
            int v=father[i];
            if(v>0&&low[i]>dfn[v])/*桥的条件*/
                printf("%d,%d
    ",v,i);
        }
    }
    void solve() {
        init();
      //  scanf("%d%d", &n, &m);
        cin >> n >> m;
        for (int i = 0; i < N; i++)  G[i].clear();
        for (int i = 0; i < m; i++) {
            int a, b;  scanf("%d%d", &a, &b);
            G[a].push_back(b);
            G[b].push_back(a);
        }
        int rootson=0;
        cnt();
    }
    int main() {
        int t = 1;
        //scanf("%d", &t);
        while(t--)
            solve();
        return 0;
    }
  • 相关阅读:
    Js高程:教你如何写出可维护的代码
    ES6 尾调用和尾递归
    js判断对象是否为空对象,判断对象中是否有某属性
    WebSocket断开原因、心跳机制防止自动断开连接
    Js闭包使用姿势指南
    浏览器事件模型
    Js数组排序
    简单的前端错误处理
    移动端做弹窗类页面注意事项
    加载时常统计
  • 原文地址:https://www.cnblogs.com/gggyt/p/6411538.html
Copyright © 2011-2022 走看看