Tarjan算法就不说了
想学看这
https://www.byvoid.com/blog/scc-tarjan/
https://www.byvoid.com/blog/biconnect/
下面是几份基本的模版
首先是无向图割点桥的代码
下面的代码是用于求割点数目的
其中add_block[u] = x 表示删除u点之后增加的联通块个数。注意是增加的联通块个数
const int MAXN = 1010; const int MAXM = 10010; const int INF = 0x3f3f3f3f; struct Edge { int u,v,next; int w; bool cut; }edge[MAXN]; int head[MAXN],tot; int Low[MAXN],DFN[MAXN],Stack[MAXN]; int Index,top; bool Instack[MAXN]; bool cut[MAXN]; int add_block[MAXN]; int N,bridge; void init() { tot = 0; memset(head,-1,sizeof(head)); } void add_edge(int u,int v,int w) { edge[tot].u = u; edge[tot].v = v; edge[tot].w = w; edge[tot].next = head[u]; head[u] = tot++; } void Tarjan(int u,int pre) { int v; Low[u] = DFN[u] = ++Index; Stack[top++] = u; Instack[u] = true; int son = 0; for (int i = head[u] ; i != -1 ; i = edge[i].next) { v = edge[i].v; if (v == pre) continue; if (!DFN[v]) { son++; Tarjan(v,u); if (Low[u] > Low[v]) Low[u] = Low[v]; if (Low[u] > DFN[v]) { bridge++; edge[i].cut = true; edge[i ^ 1].cut = true; } if (u != pre && Low[v] >= DFN[u]) { cut[u] = true; add_block[u]++; } } else if (Low[u] > DFN[v]) Low[u] = DFN[v]; } if (u == pre && son > 1) cut[u] = true; if (u == pre) add_block[u] = son - 1; Instack[u] = false; top--; } void slove() { memset(DFN,0,sizeof(DFN)); memset(Instack,false,sizeof(Instack)); memset(cut,false,sizeof(cut)); memset(add_block,0,sizeof(add_block)); top = Index = 0; bridge = 0; for (int i = 1 ; i <= N ; i++) if (!DFN[i]) Tarjan(i,i); int ret = 0; for (int i = 1 ; i <= N ; i++) if (cut[i]) ret++; printf("%d\n",ret); }