社区讨论

关于tanjar求割点对根节点处理的另一种方式

P3388【模板】割点(割顶)参与者 5已保存回复 16

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
16 条
当前快照
1 份
快照标识符
@lobcjdfg
此快照首次捕获于
2023/10/29 18:46
2 年前
此快照最后确认于
2023/11/04 00:31
2 年前
查看原帖
rt,lz写的时候用了c[]数组储存每个点(包括根节点)的子树个数,最后把根节点的计数-1,然后认为任何c[x]>=1是割点
但是wa了,不知道是思路错误还是敲错了 求指点
代码:
CPP
#include<bits/stdc++.h>
using namespace std;
int read() {
	char ch=getchar();
	int ans=0;
	while(ch<'0'||ch>'9') ch=getchar();
	while(ch>='0'&&ch<='9') {
		ans*=10;
		ans+=ch-'0';
		ch=getchar();
	}
	return ans;
}
int tot=1;
int nxt[200005],fri[200005],son[200005];
void add(int x,int y) {
	tot++;
	nxt[tot]=fri[x];
	fri[x]=tot;
	son[tot]=y;
}
int c[20004];
int low[20004],dfn[20004];
int num=0;
void tanjar(int x) {
	num++;
	low[x]=num;
	dfn[x]=num;
	for(int i=fri[x]; i; i=nxt[i]) {
		if(!dfn[son[i]]) {
			tanjar(son[i]);
			low[x]=min(low[x],low[son[i]]);
			if(dfn[x]<=low[son[i]]) {
				c[x]++;//<--这个 
			}
		}
		else {
			low[x]=min(low[x],dfn[son[i]]);
		}
	}
}
int main() {
	int n,m;
	n=read();
	m=read();
	for(int i=1; i<=m; i++) {
		int x=read(),y=read();
		if(x==y) continue;
		add(x,y);
		add(y,x);
	}
	for(int i=1; i<=n; i++) {
		if(!dfn[i]) {
			tanjar(i);
			c[i]--;//<--根节点要两个儿子所以减掉一个 
		}
	}
	int cnt=0;
	for(int i=1; i<=n; i++) {
		if(c[i]) cnt++;
	}
	cout<<cnt<<endl;
	for(int i=1; i<=n; i++) {
		if(c[i]) cout<<i<<" ";
	}
	return 0;
}

回复

16 条回复,欢迎继续交流。

正在加载回复...