1. 程式人生 > 其它 >演算法整理 & 複習:割點、割邊

演算法整理 & 複習:割點、割邊

技術標籤:資料結構與演算法tarjan割點割邊

文章目錄




一、割點(割頂)


P3388 【模板】割點(割頂)

#include <stdio.h>
#include <iostream>
using namespace std;
#define MAXN 200005

int n,m;
int cnt,flag;
int head[MAXN];
int dfn[MAXN],low[MAXN],cut[MAXN];

struct node{
	int to,next;
}map[MAXN];

void add(int
u,int v){ map[++cnt] = (node){v,head[u]}; head[u] = cnt; } void tarjan(int u, int root){ dfn[u] = low[u] = ++flag; int cur = 0; for(int k=head[u];k;k=map[k].next){ int v = map[k].to; if(!dfn[v]){ ++cur; tarjan(v,root); low[u] = min(low[u],low[v]); if((u==root && cur>
1) || (u!=root && dfn[u]<=low[v])) cut[u] = 1; } else low[u] = min(low[u],dfn[v]); } } int main(void){ cin >> n >> m; for(int i=1;i<=m;i++){ int u,v; cin >> u >> v; add(u,v); add(v,u); } for(int i=1;i<=n;i++){ 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 << " "; } return 0; }



二、割邊(橋)


tarjan(int u){
	dfn[u] = low[u] = ++flag;
	for(int k=head[u];k;k=map[k].next){
		int v = map[k].to;
		if(!dfn[v]){
			tarjan(v);
			low[u] = min(low[u],low[v]);
			if(dfn[u] < low[v]) cut[k] = 1; // 這裡記的是邊的序號
		}
		else low[u] = min(low[u],dfn[v]);
	}
}





返回