割点(割顶):一个结点称为割点(或者割顶)当且仅当去掉该节点极其相关的边之后的子图不连通。
模板题:https://www.luogu.org/problemnew/show/P3388
#include<bits/stdc++.h>
using namespace std;
const int maxn = 3e5 + 5;
int n, m, inde;
vector<int> P[maxn];
int low[maxn], dfn[maxn];
set<int> ans;//割点
void tarjan(int u, int fa)
{
low[u] = dfn[u] = ++inde;
int flag = 0;
for(auto v: P[u])
{
if(v == fa) continue;
if(dfn[v] == -1)
{
flag++;
tarjan(v, u);
low[u] = min(low[u], low[v]);
if(low[v] >= dfn[u])
ans.insert(u);
}
else
low[u] = min(low[u], dfn[v]);
}
if(fa ==-1 && flag == 1)
ans.erase(u);
}
void init()
{
memset(low, -1, sizeof(low));
memset(dfn, -1, sizeof(dfn));
ans.clear();
for(int i = 0; i <= n; i++)
P[i].clear();
inde = 0;
}
int32_t main()
{
ios_base::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
cin >> n >> m;
init();
int u, v;
for(int i = 0; i < m; i++)
{
cin >> u >> v;
P[u].push_back(v);
P[v].push_back(u);
}
for(int i = 1; i <= n; i++)
if(dfn[i] == -1)
tarjan(i, -1);
cout << ans.size() << endl;
for(int v: ans)
cout << v << " ";
return 0;
}
桥(割边):一条边称为桥(或者割边)当且仅当去掉该边之后的子图不连通。
模板题:https://cn.vjudge.net/problem/UVA-796
#include<bits/stdc++.h>
using namespace std;
const int maxn = 3e5 + 5;
int n, m, inde;
vector<int> P[maxn];
int low[maxn], dfn[maxn];
set<pair<int, int> > ans;
void tarjan(int u, int fa)
{
low[u] = dfn[u] = ++inde;
for(auto v: P[u])
{
if(v == fa) continue;
if(dfn[v] == -1)
{
tarjan(v, u);
low[u] = min(low[u], low[v]);
if(low[v] > dfn[u])
{
if(u < v)
ans.insert({u, v});
else
ans.insert({v, u});
}
}
else
low[u] = min(low[u], dfn[v]);
}
}
void init()
{
memset(low, -1, sizeof(low));
memset(dfn, -1, sizeof(dfn));
ans.clear();
for(int i = 0; i <= n; i++)
P[i].clear();
inde = 0;
}
int32_t main()
{
/*ios_base::sync_with_stdio(0);
cin.tie(0); cout.tie(0);*/
while(cin >> n)
{
init();
int u, v, m;
for(int i = 0; i < n; i++)
{
scanf("%d (%d)", &u, &m);
while(m--)
{
cin >> v;
if(u >= v) continue;
P[u].push_back(v);
P[v].push_back(u);
}
}
for(int i = 1; i <= n; i++)
if(dfn[i] == -1)
tarjan(i, -1);
printf("%d critical links\n",ans.size());
for(auto x: ans)
cout << x.first << " - " << x.second << endl;
cout << endl;
}
return 0;
}