tarjan,割边,桥,割点

Posted codemaker-li

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了tarjan,割边,桥,割点相关的知识,希望对你有一定的参考价值。

这里是tarjan的基础知识,

求割点和割边


 

先来求割边,

#include <cstdio>
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;

#define ls (t<<1)
#define rs ((t<<1)|1)
#define mid ((l+r)>>1)

#define mk make_pair
#define pb push_back
#define fi first
#define se second

#define MAXN 100001
struct edge {
    int v,nxt;
} e[MAXN*2];
int head[MAXN];
bool qiao[MAXN*2];
int dfn[MAXN],low[MAXN];
int n,m,cnt,num;
void add(int x,int y) {
    e[++cnt].v=y,e[cnt].nxt=head[x],head[x]=cnt;
}
void tarjan(int x,int fa) {
    dfn[x]=low[x]=++num;
    for (int i=head[x]; i; i=e[i].nxt) {
        int y=e[i].v;
        if (!dfn[y]) {
            tarjan(y,i);
            low[x]=min(low[x],low[y]);
            if (low[y]>dfn[x]) {
                qiao[i]=qiao[i^1]=1;
            }
        } else if(i!=(fa^1)) {
            low[x]=min(low[x],dfn[y]);
        }
    }
}

int main() {
    cin>>n>>m;
    cnt=1;
    for (int i=1,x,y; i<=m; i++) {
        cin>>x>>y;
        add(x,y),add(y,x);
    }
    for (int i=1; i<=n; i++) {
        if (!dfn[i]) {
            tarjan(i,0);
        }
    }
    for (int i=2; i<cnt; i+=2) {
        if (qiao[i]) {
            cout<<e[i^1].v<<" "<<e[i].v<<endl;
        }
    }
    return 0;
}

/*
6 7
1 2
1 3
2 3
2 4
4 5
4 6
5 6
*/

下面是割点

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <bits/stdc++.h>
 4 using namespace std;
 5 typedef long long ll;
 6 typedef unsigned long long ull;
 7 
 8 #define ls (t<<1)
 9 #define rs ((t<<1)|1)
10 #define mid ((l+r)>>1)
11 
12 #define mk make_pair
13 #define pb push_back
14 #define fi first
15 #define se second
16 
17 #define MAXN 100001
18 struct edge {
19     int v,nxt;
20 } e[MAXN*2];
21 int head[MAXN];
22 bool cut[MAXN];
23 int dfn[MAXN],low[MAXN];
24 int n,m,cnt,num,root;
25 void add(int x,int y) {
26     e[++cnt].v=y,e[cnt].nxt=head[x],head[x]=cnt;
27 }
28 void tarjan(int x) {
29     dfn[x]=low[x]=++num;
30     int flag=0;
31     for (int i=head[x]; i; i=e[i].nxt) {
32         int y=e[i].v;
33         if (!dfn[y]) {
34             tarjan(y);
35             low[x]=min(low[x],low[y]);
36             if (low[y]>=dfn[x]) {
37                 flag++;
38                 if (x!=root||flag>1) {
39                     cut[x]=1;
40                 }
41             }
42         } 
43         else low[x]=min(low[x],dfn[y]);
44     }
45 }
46 
47 int main() {
48     cin>>n>>m;
49     cnt=1;
50     for (int i=1,x,y; i<=m; i++) {
51         cin>>x>>y;
52         if (x==y) continue;
53         add(x,y),add(y,x);
54     }
55     for (int i=1; i<=n; i++) {
56         if (!dfn[i]) {
57             root=i;
58             tarjan(i);
59         }
60     }
61     for (int i=1; i<=n; i++) {
62         if (cut[i]) {
63             cout<<i<<" ";
64         }
65     }
66     cout<<"是个割点"<<endl;
67     return 0;
68 }
69 
70 /*
71 6 6
72 1 2
73 1 3
74 2 3
75 2 4
76 2 5
77 4 5
78 */

 

以上是关于tarjan,割边,桥,割点的主要内容,如果未能解决你的问题,请参考以下文章

图论分支-Tarjan初步-割点和割边

8/15 缩点+割点(割顶)+桥(割边)+字符串哈希

关于Tarjan

tarjan-无向图(求割点)

Tarjan算法:求解图的割点与桥(割边)

Tarjan算法与割点割边