输入输出样例
输入 #1复制
6 7 1 2 1 3 1 4 2 5 3 5 4 5 5 6
输出 #1复制
1 5
说明/提示
对于全部数据,n \le 20000n≤20000,m \le 100000m≤100000
点的编号均大于00小于等于nn。
tarjan图不一定联通。
一道tarjan求割点的裸题
#include<bits/stdc++.h>
using namespace std;
const int maxn = 3e6 + 10;
int head[maxn];
int dfn[maxn];
int low[maxn];
bool vis[maxn];
int tot;
int dex;
int cnt = 0;
int n, m;
struct node{
int to;
int next;
node() {}
node(int a, int b) : to(a), next(b) {}
}edge[maxn];
void edgeadd(int a, int b){
edge[tot] = node(b, head[a]);
head[a] = tot++;
}
void init(){
memset(head, -1, sizeof(head));
memset(vis, 0, sizeof(vis));
memset(dfn, 0, sizeof(dfn));
tot = 0;
dex = 0;
}
set<int> t;
void tarjan(int u, int rt){
dfn[u] = low[u] = ++dex;
int ans = 0;
for(int i = head[u]; i != -1; i = edge[i].next){
int v = edge[i].to;
if(dfn[v] == 0){
ans++;
tarjan(v, rt);
low[u] = min(low[u], low[v]);
if(u != rt && low[v] >= dfn[u])
t.insert(u);
}
low[u] = min(low[u], dfn[v]);
}
if(u == rt && ans >= 2)
t.insert(u);
}
int main(){
ios::sync_with_stdio(false);
cin >> n >> m;
init();
int x, y;
for(int i = 1; i <= m; i++){
cin >> x >> y;
edgeadd(x, y);
edgeadd(y, x);
}
for(int i = 1; i <= n; i++){
if(!dfn[i])
tarjan(i, i);
}
int r;
r = t.size();
cout << r << endl;
set<int>::iterator it;
for(it = t.begin(); it != t.end(); it++) //使用迭代器进行遍历
{
cout << *it << " ";
}
cout << endl;
return 0;
}