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,割边,桥,割点的主要内容,如果未能解决你的问题,请参考以下文章