割点
代码如下:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cstdio>
using namespace std;
#define N 10000
vector<int>G[N+10];
int low[N+10], num[N+10], vis[N+10];
int n, m, index;//index为走过的点的编号
void Cutpoint(int cur, int father)
{
index++;
num[cur] = index;
low[cur] = index;
for(int i = 0; i < G[cur].size(); i++)
{
int cnode = G[cur][i];
if(num[cnode] == 0)
{
Cutpoint(cnode, cur);
low[cur] = min(low[cur], low[cnode]);
if(num[cur] <= low[cnode])//割边的话改为if(num[cur] < low[cnode])即可
vis[cur] = 1; //割边: printf("%d %d\n", cur, cnode);
}
else if(cnode != father)
low[cur] = min(low[cur],num[cnode]);
}
return ;
}
int main()
{
while(~scanf("%d %d", &n, &m))
{
memset(vis, 0, sizeof(vis));
memset(num, 0, sizeof(num));
int a, b;
for(int i = 0; i <= n; i++)
G[i].clear();
while(m--)
{
scanf("%d %d", &a, &b);
G[a].push_back(b);
G[b].push_back(a);
}
index = 0;
Cutpoint(1, 1);
int ans = 0;
for(int i = 1; i <= n; i++)
if(vis[i])
{
ans++;
printf("%d ", i);
}
printf("%d\n", ans);
}
return 0;
}