Blog of RuSun

\begin {array}{c} \mathfrak {One Problem Is Difficult} \\\\ \mathfrak {Because You Don't Know} \\\\ \mathfrak {Why It Is Diffucult} \end {array}

Tarjan 模板

用于图的缩点、求割点和桥。

Strongly Connected Component

查看代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
void tarjan(int x)
{
dfn[x] = low[x] = ++stmp;
stk.push(x);
vis[x] = true;
for (int i = hd[x]; ~i; i = nxt[i])
if (!dfn[edg[i]])
{
tarjan(edg[i]);
low[x] = min(low[x], low[edg[i]]);
}
else if (vis[edg[i]])
low[x] = min(low[x], dfn[edg[i]]);
if (dfn[x] == low[x])
{
cnt++;
int y;
do
{
y = stk.top();
stk.pop();
vis[y] = false;
//
} while (y != x);
}
}

Double Connected Component

查看代码
1
2
3
4
5
6
7
8
9
10
11
12
13
void tarjan(int x, int fa)
{
dfn[x] = low[x] = ++stmp;
for (int i = hd[x]; ~i; i = nxt[i]) if (i ^ fa ^ 1)
if (!dfn[edg[i]])
{
tarjan(edg[i], i);
low[x] = min(low[x], low[edg[i]]);
if (dfn[x] < low[edg[i]]) bridge[i] = bridge[i ^ 1] = true;
}
else
low[x] = min(low[x], dfn[edg[i]]);
}

Vertex Double Connected Component

Check the root point specially.

因为判断可以取等,所以不必考虑来边。

查看代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void tarjan (int x, int rt)
{
dfn[x] = low[x] = ++stmp;
int cnt = 0;
for (int i : g[x])
if (!dfn[i])
{
++cnt;
tarjan(i, rt);
low[x] = min(low[x], low[i]);
if (low[i] >= dfn[x] && x ^ rt) cut[x] = true;
}
else low[x] = min(low[x], dfn[i]);
if (x == rt && cnt > 1) cut[x] = true;
}