Tarjan 基础用法 (仅代码版)
作者:互联网
struct Tarjan { int dfn[maxn], low[maxn], Time; bool vis_cutnode[maxn], vis_bridge[maxn]; combo Tarjan_gd(int u, int fa) {//有/无 向图的割点 dfn[u] = low[u] = ++ Time; int cnt = 0; for (int i = heade[u]; i; i = e[i].next) { int v = e[i].to; if(! dfn[v]) { Tarjan_gd(v, u); low[u] = min(low[u], low[v]); if(low[v] >= dfn[u]) { cnt ++; if(fa != 0 || cnt > 1) { vis_cutnode[u] = true; } } else { low[u] = min(low[u], dfn[v]); } } } return; } combo Tarjan_gb(int u, int id_edge) {//有/无 向图的割边 dfn[u] = low[u] = ++ Time; for (int i = heade[u]; i; i = e[i].next) { int v = e[i].to; if(i == id_edge ^ 1) continue; if(! dfn[v]) { Tarjan_gb(v, i); low[u] = min(low[u], low[v]); if(low[v] > dfn[u]) { vis_bridge[i] = vis_bridge[i ^ 1] = true; } } else { low[u] = min(low[u], dfn[v]); } } return; } //SD//缩点 (有向图) int st[maxn], top, tot_s; int belong[maxn]; combo Tarjan_sd(int u)//缩点 (有向图) { dfn[u] = low[u] = ++ Time; st[++ top] = u; for (int i = heade[u]; i; i = e[i].next) { int v = e[i].to; if(!dfn[v]) { Tarjan_sd(v); low[u] = min(low[u], low[v]); } else { low[u] = min(low[u], dfn[v]); } } if(dfn[u] == low[u]) { tot_s ++; while(st[top + 1] != u) { belong[st[top --]] = tot_s; } } return; } //v_DCC//点双联通分量 (无向图) int num, tot_v; int new_id[maxn]\; vector <int> v_dcc[maxn]; combo Tarjan_ds(int u, int fa) {//无向图的点双联通分量 v_DCC dfn[u] = low[u] = ++ Time; st[++ top] = u; if(fa == 0 && heade[u] == 0) { v_dcc[++ tot_v].push_back(u); return; } int cnt = 0; for (int i = heade[u]; i; i = e[i].next) { int v = e[i].to; if(! dfn[v]) { Tarjan_ds(v, u); low[u] = min(low[u], low[v]); if(low[v] >= dfn[u]) { cnt ++; if(fa != 0 || cnt > 0) vis_cutnode[u] = true; while(st[top + 1] != v) { v_dcc[++ tot_v].push_back(st[top --]); } } } else { low[u] = min(low[u], dfn[v]); } } return; } combo get_ds_sd() { num = tot_v; for (int i = 1; i <= n; ++ i) { if(vis_cutnode[i]) { new_id[i] = ++ num; } } for (int i = 1; i <= tot_v; ++ i) { for (int j = 0; j < v_dcc[i].size(); ++ j) { int u = v_dcc[i][j]; if(vis_cutnode[u]) { Insertg(i, new_id[u]), Insertg(new_id[u], i); } else { belong[u] = i; } } } return; } //e_DCC//边双联通分量 (无向图) int e_DCC[maxn], tot_e; combo Dfs_e_DCC(int u) { e_DCC[u] = tot_e; for (int i = heade[u]; i; i = e[i].next) { int v = e[i].to; if(e_DCC[v] || vis_bridge[i]) continue; Dfs_e_DCC(v); } } combo get_bs() {//无向图的边双联通分量 e_DCC for (int i = 1; i <= n; ++ i) { if(!e_DCC[i]) { ++ tot_e; Dfs_e_DCC(i); } } return; } combo get_bs_sd() {//边双联通分量的缩点 for (int i = 2; i <= tote; ++ i) { int u = e[i ^ 1].to, v = e[i].to; if(e_DCC[u] == e_DCC[v]) continue; Insertg(u, v); } } }T;
标签:Tarjan,min,int,代码,用法,++,dfn,low 来源: https://www.cnblogs.com/liyikang/p/16492154.html