关于dsu on tree写法
  • 板块CF1709E XOR Tree
  • 楼主Kniqht
  • 当前回复6
  • 已保存回复6
  • 发布时间2023/12/14 22:38
  • 上次更新2023/12/15 08:44:04
查看原帖
关于dsu on tree写法
315205
Kniqht楼主2023/12/14 22:38

rt,看到第一篇写的很短就贺了一下

这个dsu是这样写的:一边搜索儿子v一边更新u点的set,然后若儿子更大就交换set,然后将原来u的set插入儿子的set中。若儿子的set更小就将儿子的插入u的set中

但是我想的是这样写:第一遍先求出u的重儿子,然后再来一遍进行启发式合并。

第一种写法真的对吗??感觉会不会出现问题啊

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int n;
int h[N],e[N*2],ne[N*2],idx;
int a[N],f[N];
void add(int a,int b){
	e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
set<int> s[N];
int son[N],cnt;
void dfs(int u,int fa){
	s[u].insert(f[u]);
	bool flag=0;
	for(int i=h[u];~i;i=ne[i]){
		int j=e[i];
		if(j==fa) continue;
		f[j]=f[u]^a[j];
		dfs(j,u);
		if(s[u].size()<s[j].size()) swap(s[u],s[j]);
		for(int k:s[j])
		    if(s[u].count(a[u]^k))flag=1;
		for(int k:s[j]) s[u].insert(k);
	}
	if(flag)cnt++,s[u].clear();
}
signed main(){
    memset(h,-1,sizeof(h));
    scanf("%d",&n);int u,v;
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    for(int i=1;i<n;i++){
    	scanf("%d%d",&u,&v);
    	add(u,v);add(v,u);
	}
	f[1]=a[1];
	dfs(1,-1);
	printf("%d",cnt);
	return 0;
}   
2023/12/14 22:38
加载中...