社区讨论
关于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 条回复,欢迎继续交流。
正在加载回复...