标签:ext 删掉 大于 == register image 自己的 struct com
在一个无向图G中,存在一个点集V,从图G中删掉所有属于V的点及其与之相连的边,G不连通。如果有一个边集E,删掉所有属于这个集合的边,G不连通。
两个割点之间的边不一定是割边
割边的端点不一定是割点
一个图可能有多个割点,有多个桥
#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAXN 100005
int head[MAXN];
struct edge{
int v,next;
}G[MAXN<<1];
int tot = 0;
int dfn[MAXN],low[MAXN],num = 0;
int ans[MAXN];
int N,M;
inline void add(int u,int v){
G[++tot].v = v;G[tot].next = head[u];head[u] = tot;
}
void tarjan(int u,int fa){
dfn[u] = low[u] = ++num;
int count = 0;//统计子树数量
for(register int i=head[u];i;i=G[i].next){
int v = G[i].v;
if(!dfn[v]){
tarjan(v,u);
++count;//子树数量+1
low[u] = std::min(low[u],low[v]);
if(low[v]>=dfn[u]&&u!=fa)ans[u] = 1;// 如果u不是根节点
}
low[u] = std::min(low[u],dfn[v]);
}
if(count>=2&&u==fa)ans[u] = 1;//如果u是根节点,且有两个及两个以上的子树
}
int main(){
std::memset(head,0,sizeof(head));
std::memset(ans,0,sizeof(ans));
std::memset(dfn,0,sizeof(dfn));
scanf("%d%d",&N,&M);
int u,v;
for(register int i=1;i<=M;++i){
scanf("%d%d",&u,&v);
add(u,v);add(v,u);
}
for(register int i=1;i<=N;++i){
if(!dfn[i])tarjan(i,i);
}
int count = 0;
for(register int i=1;i<=N;++i){
if(ans[i])++count;
}
printf("%d\n",count);
for(register int i=1;i<=N;++i){
if(ans[i])printf("%d ",i);
}
return 0;
}
标签:ext 删掉 大于 == register image 自己的 struct com
原文地址:https://www.cnblogs.com/Neworld2002/p/9575399.html