1. 程式人生 > 其它 >模板【割點和點雙連通分量】

模板【割點和點雙連通分量】

PART1(演算法思想簡介)

1.實現:

2.時間複雜度:

3.特別優勢:

4.適用情況:

5.需要注意的點:

6:函式、變數名的解釋+英文:

bcc(Biconnected component)(雙連通分量)

邊雙聯通 eBcc

點雙連通 vBcc

int timeStamp(時間戳)

int dfn[i](訪問到i時的時間戳)

int low[i](i及其子結點所能訪問到的最小的時間戳)

bool iscut[i](i是否為割點)

set<int> eBcc[i](儲存第i個ebcc上的點)

set<int> vBcc[i](儲存第i個vbcc上的點)

stack<edgeK> S(儲存經過的邊)

PART2(演算法各種型別(並附上程式碼))

可用程式碼

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<cstring>
#include<string>
#include<vector>
#include<queue>
#include<iomanip>
#include<iostream>
#include<stack>
using
namespace std; #define inf 0x3f3f3f3f const int N = 1e2+10; const int M = 1e4+10; //與邊相關 struct edgeK { int u, v, next, w; } eK[M]; int pK[N], eidK; inline void InitEdgeK() { memset(pK, -1, sizeof(pK)); eidK = 0; } inline void InsertK(int u, int v, int w = 0) { eK[eidK].next = pK[u]; eK[eidK].next
= pK[u]; eK[eidK].v = v; eK[eidK].w = w; pK[u] = eidK++; } //縮點 int timeStamp = 0; int dfn[N], low[N]; int vBccCnt = 0; bool iscut[N]; set<int> vBcc[N]; stack<edgeK> S; void dfsVBcc(int u, int fa) { dfn[u] = low[u] = ++timeStamp; int child = 0; for(int i = pK[u]; i != -1; i = eK[i].next) { int v = eK[i].v; if(dfn[v] == 0) { S.push(eK[i]); ++child; dfsVBcc(v, u); low[u] = min(low[u], low[v]); if(low[v] >= dfn[u]) //但凡找到一個這樣的子樹使得此點為割點,就把該子樹割出來 { iscut[u] = true; ++vBccCnt; while(true) { edgeK x = S.top(); S.pop(); vBcc[vBccCnt].insert(x.u); vBcc[vBccCnt].insert(x.v); if(x.u == u && x.v == v) { break; } } } } else if(dfn[v] < dfn[u] && v != fa) { S.push(eK[i]); low[u] = min(low[u], dfn[v]); } } if(fa < 0 && child == 1) { iscut[u] = false; } } int main() { //freopen("in.txt","r", stdin); //freopen("out.txt","w", stdout); ios::sync_with_stdio(false); InitEdgeK(); int n, m; cin >> n >> m; for (int i = 0; i < m; ++i) { int u, v; cin >> u >> v; InsertK(u, v); InsertK(v, u); } memset(dfn, 0, sizeof(dfn)); timeStamp = vBccCnt = 0; dfsVBcc(1, -1); cout << vBccCnt << endl; for(int i = 1; i <= vBccCnt; ++i) { for(set<int>::iterator it = vBcc[i].begin(); it != vBcc[i].end(); ++it) { cout << (*it) << " "; } cout << endl; } return 0; }
View Code

PART3(演算法的延伸應用)

PART4(對演算法深度的理解)

PART5(與其相關的有趣題目)