1. 程式人生 > >割點-割邊(橋)模板

割點-割邊(橋)模板

割點

在一個無向圖中,如果有一個頂點集合,刪除這個頂點集合以及這個集合中所有頂點相關聯的邊以後,圖的連通分量增多,就稱這個點集為割點集合。

注意: 1、討論割點是在無向圖中。 2、刪除這個點使圖的聯通分量增多就是割點,所以非連通圖也有割點。

割邊(橋)

假設有連通圖G,e是其中一條邊,如果G-e是不連通的,則邊e是圖G的一條割邊。此情形下,G-e必包含兩個連通分支。

為什麼必包含兩個?因為一條邊最多連兩個點。。。

我就不多介紹了,再說就是誤導人了

沒錯我就是來發個模板的,大家可以參考參考,還是滿規範的

割點割邊寫起來比縮點還是短不少的。

#include <iostream>
#include <vector> using namespace std; const int maxn = 10010; int n, m, id = 0; int cut[maxn] = {}; vector<int> G[maxn]; int dfn[maxn] = {}, low[maxn]; void tarjan(int u, int root) { int child = 0; dfn[u] = low[u] = ++id; for (size_t i = 0; i < G[u].size(); ++i) { int
v = G[u][i]; if (dfn[v] == 0) { tarjan(v, root); low[u] = min(low[u], low[v]); if (u != root && low[v] >= dfn[u]) cut[u] = true; if (u == root) child++; } low[u] = min(low[u], dfn[v]); } if (u == root && child >= 2
) cut[root] = true; } int main() { cin >> n >> m; for (int i = 1; i <= m; ++i) { int x, y; cin >> x >> y; G[x].push_back(y); G[y].push_back(x); } for (int i = 1; i <= n; ++i) { if (dfn[i] == 0) tarjan(i, i); } int ans = 0; for (int i = 1; i <= n; ++i) { if (cut[i]) ans++; } cout << ans << endl; for (int i = 1; i <= n; ++i) { if (cut[i]) cout << i << ' '; } cout << endl; }

割邊(無模板題)

#include <iostream>
using namespace std;

struct Edge {
    int to, next;
};

const int maxn = 10010;
int n, m, id = 0, cnt = 1;
Edge edge[maxn], cut[maxn];
int dfn[maxn] = {}, low[maxn];
int head[maxn] = {}, baba[maxn] = {};
int tou[maxn] = {};

void Add(Edge *edge, int u, int v, int *head)
{
    edge[cnt].to = v;
    edge[cnt].next = head[u];
    head[u] = cnt++;
}

void tarjan(int u)
{
    dfn[u] = low[u] = ++id;
    for (int i = head[u]; i; i = edge[i].next) {
        int v = edge[i].to;
        if (baba[u] == v) continue;
        if (dfn[v] == 0) {
            baba[v] = u;
            tarjan(v);
            low[u] = min(low[u], low[v]);
            if (low[v] > dfn[u]) Add(cut, u, v, tou);
        }
        low[u] = min(low[u], dfn[v]);
    }
}

int main()
{
    cin >> n >> m;
    for (int i = 1; i <= m; ++i) {
        int x, y;
        cin >> x >> y;
        Add(edge, x, y, head);
        Add(edge, y, x, head);
    }
    for (int i = 1; i <= n; ++i) {
        if (dfn[i] == 0) tarjan(i);
    }
    for (int u = 1; u <= n; ++u) {
        for (int i = tou[u]; i; i = cut[i].next) {
            cout << u << ' ' << cut[i].to << endl;
        }
    }
}