P3388 [template] point cut (top cut) (tarjan find cut points templates)

Topic Link

Meaning of the questions: Given an undirected graph, find the number of cut points.

Solution: What is the cut point? Simply put, if delete a point, drawing a diagram into a multiple, then this point is called a cut point.

New Method for cutting points or uses tarjan algorithm, but with China Unicom and strong component tarjan be slightly different.

For the root node, as long as the judge whether there are two or more sub-son.

For non-root node, if the low [v]> = dfn [u], u is able to determine a cut point. Because you can not be low [v] updates, the ring does not exist, because there is only a low entire Unicom will be updated component in the presence of the ring. So we can determine this point is cut point.

#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn = 1e5+100;
struct edge{
	int next,v;
}e[maxn*2];
int head[maxn],low[maxn],dfn[maxn],cut[maxn];
int cnt,tot;
void insert(int u,int v){
	e[++tot].next=head[u];e[tot].v=v;head[u]=tot;
	e[++tot].next=head[v];e[tot].v=u;head[v]=tot;
}
void tarjan(int u,int fa){
	dfn[u]=low[u]=++cnt;
	int child=0;
	for(int i=head[u];i;i=e[i].next){
		int v = e[i].v;
		if(!dfn[v]){
			tarjan(v,fa);
			low[u]=min(low[u],low[v]);
			if(low[v]>=dfn[u]&&u!=fa) cut[u]=1;
			if(u==fa) child++;
		}
		low[u]=min(low[u],dfn[v]);//一定要是dfn[v],因为v的low值可能在之前被更新了,这样v本来可以是一个割点的,但是low[u]<dfn[v],会造成答案减少。
		//具体可以看我下面举的一组样例 
	}
	if(child>=2&&u==fa) cut[u]=1;//如果是根节点,并且有两个儿子 ,那么就是割点 
}
int main()
{
	int n,m,u,v;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++){
		scanf("%d%d",&u,&v);
		insert(u,v);
	}
	for(int i=1;i<=n;i++){
		if(!dfn[i]) tarjan(i,i);
	}
	int ans=0;
	for(int i=1;i<=n;i++) if(cut[i]) ans++;
	printf("%d\n",ans);
	for(int i=1;i<=n;i++) if(cut[i]) printf("%d ",i);
	puts("");
}
/* 
4 4 
1 2
2 3
3 1
2 4
*/ 

 

Guess you like

Origin blog.csdn.net/qq_42129242/article/details/90943893
cut