模板【割點和點雙連通分量】
阿新 • • 發佈:2021-07-01
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> usingView Codenamespace 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; }
PART3(演算法的延伸應用)
PART4(對演算法深度的理解)
PART5(與其相關的有趣題目)