洛谷__P3388 【模板】割点(割顶)
题目链接:P3388 【模板】割点(割顶) - 洛谷
题目描述:
给出一个 个点, 条边的无向图,求图的割点。
割点:
在图上删除一个点后变为不连通,(从一整块变成两块以上...)
代码:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<deque>
#include<stack>
#include<set>
#include<map>
#include<unordered_set>
#include<unordered_map>
#include<bitset>
#include<tuple>
#define inf 9187201950435737471
#define int long long
#define endl '\n'
#define F first
#define S second
using namespace std;
typedef pair<int, int> pii;
const int N = 20086, M = 200086;
int n, m, root;
int h[N], ne[M], e[M], idx;
int dfn[N], low[N], ti;
stack<int> st;
bool cut[N];
set<int> res;
void add(int a, int b) {
e[idx] = b;
ne[idx] = h[a];
h[a] = idx++;
}
void tarjan(int u) {
dfn[u] = low[u] = ++ti;
int cnt = 0;
for (int i = h[u]; ~i; i = ne[i]) {
int j = e[i];
if (!dfn[j]) {
cnt++;
tarjan(j);
low[u] = min(low[u], low[j]);
if (dfn[u] <= low[j] && root != u) res.insert(u);
if (u == root && cnt >= 2) res.insert(u);
} else low[u] = min(low[u], dfn[j]);
}
}
void solve() {
memset(h, -1, sizeof h);
cin >> n >> m;
while (m--) {
int a, b;
cin >> a >> b;
if (a == b) continue;
add(a, b), add(b, a);
}
for (root = 1; root <= n; root++) {
if (!dfn[root]) tarjan(root);
}
cout << res.size() << endl;
for (auto x : res) cout << x << " ";
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int T = 1;
// cin >> T;
while (T--) solve();
return 0;
}

浙公网安备 33010602011771号