牛客多校第5场补题 B Graph 异或最小生成树

本文讨论了一种图的操作问题,涉及到在保持树联通性和环的边权异或和为0的条件下,如何进行添加和删除边。核心解决方案是利用异或运算求解最小生成树。首先计算每个节点到根节点的异或和,接着利用字典树求解最小异或值。在比赛中,虽然遇到了困难,但通过分治策略解决了如何找到两个集合中异或和最小的问题,实现了异或最小生成树的构建。
摘要由CSDN通过智能技术生成

Graph

题目链接

题目大意

给出一颗树,有两种操作,添加一条边,删除一条边。
每个时刻必须满足
如果有环那么环的边权异或和必须是0,
必须是联通的。

题解

也就是先求一下每个节点到根节点的异或和,然后用这些值的异或当边权求个最小生成树。
问题就是 知道一些点的点权,边权是两个点权异或,然后求最小生成树。
求最小异或值可以用字典树。
好了,比赛的时候就想到了这里,不会求了。然后考虑到了并查集,但是不会两个集合合并,也就是合并n - 1次,但是怎么求两个集合里的数各挑一个的异或最小值,然后就不会了好菜,连异或最小生成树都没听过

然后 异或最小生成树,可以这样求:
分治,从高位到低位考虑。最优肯定是:根据当前位分成这一位是1的和这一位是0的,左边合并完,右边合并完,然后 在左边找一个在右边找一个值合并,这样的话就可以把左边加到字典树里,遍历右边找最小的异或值。然后就相当于合并了。
显然合并了n - 1次,符合。
代码

#include <algorithm>
#include <cstdio>
#include <iostream>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <unordered_map>
#include <cmath>
#include <set>
#include <cstring>
#include <string>
#include <unordered_set>
#include <bitset>
#include <stdlib.h>
#include <time.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef unsigned long long ull;
typedef set<int>::iterator sit;
#define st first
#define sd second
#define mkp make_pair
#define pb push_back
void wenjian(){
   freopen("concatenation.in","r",stdin);freopen("concatenation.out","w",stdout);}
void tempwj(){
   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值