割点 桥

割点(割顶):一个结点称为割点(或者割顶)当且仅当去掉该节点极其相关的边之后的子图不连通。

模板题:https://www.luogu.org/problemnew/show/P3388

#include<bits/stdc++.h>

using namespace std;

const int maxn = 3e5 + 5;

int n, m, inde;
vector<int> P[maxn];
int low[maxn], dfn[maxn];
set<int> ans;//割点

void tarjan(int u, int fa)
{
    low[u] = dfn[u] = ++inde;
    int flag = 0;
    for(auto v: P[u])
    {
        if(v == fa) continue;
        if(dfn[v] == -1)
        {
            flag++;
            tarjan(v, u);
            low[u] = min(low[u], low[v]);
            if(low[v] >= dfn[u])
                ans.insert(u);
        }
        else
            low[u] = min(low[u], dfn[v]);
    }
    if(fa ==-1 && flag == 1)
        ans.erase(u);
}

void init()
{
    memset(low, -1, sizeof(low));
    memset(dfn, -1, sizeof(dfn));
    ans.clear();
    for(int i = 0; i <= n; i++)
        P[i].clear();
    inde = 0;
}

int32_t main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);

    cin >> n >> m;
    init();
    int u, v;
    for(int i = 0; i < m; i++)
    {
        cin >> u >> v;
        P[u].push_back(v);
        P[v].push_back(u);
    }
    for(int i = 1; i <= n; i++)
        if(dfn[i] == -1)
            tarjan(i, -1);
    cout << ans.size() << endl;
    for(int v: ans)
        cout << v << " ";
    return 0;
}

桥(割边):一条边称为桥(或者割边)当且仅当去掉该边之后的子图不连通。

模板题:https://cn.vjudge.net/problem/UVA-796

#include<bits/stdc++.h>

using namespace std;

const int maxn = 3e5 + 5;

int n, m, inde;
vector<int> P[maxn];
int low[maxn], dfn[maxn];
set<pair<int, int> > ans;

void tarjan(int u, int fa)
{
    low[u] = dfn[u] = ++inde;
    for(auto v: P[u])
    {
        if(v == fa) continue;
        if(dfn[v] == -1)
        {
            tarjan(v, u);
            low[u] = min(low[u], low[v]);
            if(low[v] > dfn[u])
            {
                if(u < v)
                    ans.insert({u, v});
                else
                    ans.insert({v, u});
            }
        }
        else
            low[u] = min(low[u], dfn[v]);
    }
}

void init()
{
    memset(low, -1, sizeof(low));
    memset(dfn, -1, sizeof(dfn));
    ans.clear();
    for(int i = 0; i <= n; i++)
        P[i].clear();
    inde = 0;
}

int32_t main()
{
    /*ios_base::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);*/

    while(cin >> n)
    {
        init();
        int u, v, m;
        for(int i = 0; i < n; i++)
        {
            scanf("%d (%d)", &u, &m);
            while(m--)
            {
                cin >> v;
                if(u >= v) continue;
                P[u].push_back(v);
                P[v].push_back(u);
            }
        }
        for(int i = 1; i <= n; i++)
            if(dfn[i] == -1)
                tarjan(i, -1);
        printf("%d critical links\n",ans.size());
        for(auto x: ans)
            cout << x.first << " - " << x.second << endl;
        cout << endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/k_ona/article/details/80891975