热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

Graph题目链接题目大意给出一颗树,有两种操作,添加一条边,删除一条边。每个时刻必须满足如果有环那么环的边权异或和必须是0,必须是联通的。题解也就是先求一下每个节点到根节点的异或

Graph

题目链接

题目大意

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

题解

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

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

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
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(){ freopen("hash.in","r",stdin);freopen("hash.out","w",stdout);}
ll gcd(ll a,ll b){ return b == 0 ? a : gcd(b,a % b);}
ll qpow(ll a,ll b,ll mod){ a %= mod;ll ans = 1;while(b){ if(b & 1)ans = ans * a % mod;a = a * a % mod;b >>= 1;}return ans;}
struct cmp{ bool operator()(const pii & a, const pii & b){ return a.second < b.second;}};
int lb(int x){ return x & -x;}
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll mod = 1e9 + 7;
const int maxn = 1e5+5;
int dep[maxn];
std::vector<pii> vv[maxn];
void dfs(int x,int fa,int d)
{
dep[x] = d;
for (int i = 0; i < vv[x].size(); i ++ )
{
int v = vv[x][i].st;
if(v == fa)
continue;
dfs(v,x,d ^ vv[x][i].sd);
}
}
int tree[maxn * 30][2];
int cnt =0 ;
void add(int x)
{
int p = 0;
for (int i = 30; i >= 0; i -- )
{
int f = x >> i & 1;
if(tree[p][f] == 0)
{
tree[p][f] = ++cnt;
}
p = tree[p][f];
// cout<
}
}
int query(int x)
{
int ans = 0;
int p = 0;
for (int i = 30; i >= 0; i -- )
{
int f = x >> i & 1;
if(tree[p][f])
{
p = tree[p][f];
// cout<
}
else
{
p = tree[p][!f];
ans += 1 << i;
}
}
return ans;
}
int num[maxn];
bool cmp(int a,int b)
{
return a > b;
}
ll ans =0;
void fenzhi(int l,int r,int de)
{
// printf("%d %d %d\n",l,r,de);
if(l >= r || de < 0)
return;
int mid = l;
while(mid <= r && (dep[mid] >> de & 1) == 0)
{
mid ++ ;
}
fenzhi(l,mid - 1,de - 1);
fenzhi(mid,r,de - 1);
if(mid <= l || mid > r)
return;
for (int i = l; i < mid; i ++ )
{
add(dep[i]);
}
int temp = inf;
for (int i = mid; i <= r; i ++ )
{
temp = min(temp,query(dep[i]));
}
// printf("%d %d %d %d\n",l,mid,r,temp);
ans += temp;
for (int i= 0; i <= cnt; i ++ )
{
tree[i][0] = tree[i][1] = 0;
}
cnt = 0;
}
int main()
{
int n;
scanf("%d",&n);
for (int i = 1; i < n; i ++ )
{
int x,y,val;
scanf("%d%d%d",&x,&y,&val);
vv[x].pb(mkp(y,val));
vv[y].pb(mkp(x,val));
}
dfs(0,0,0);
sort(dep,dep + n);
fenzhi(0,n - 1,30);
cout<<ans<<endl;
}

推荐阅读
  • 电话号码的字母组合解题思路和代码示例
    本文介绍了力扣题目《电话号码的字母组合》的解题思路和代码示例。通过使用哈希表和递归求解的方法,可以将给定的电话号码转换为对应的字母组合。详细的解题思路和代码示例可以帮助读者更好地理解和实现该题目。 ... [详细]
  • IhaveconfiguredanactionforaremotenotificationwhenitarrivestomyiOsapp.Iwanttwodiff ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 模板引擎StringTemplate的使用方法和特点
    本文介绍了模板引擎StringTemplate的使用方法和特点,包括强制Model和View的分离、Lazy-Evaluation、Recursive enable等。同时,还介绍了StringTemplate语法中的属性和普通字符的使用方法,并提供了向模板填充属性的示例代码。 ... [详细]
  • GreenDAO快速入门
    前言之前在自己做项目的时候,用到了GreenDAO数据库,其实对于数据库辅助工具库从OrmLite,到litePal再到GreenDAO,总是在不停的切换,但是没有真正去了解他们的 ... [详细]
  • 本文整理了Java面试中常见的问题及相关概念的解析,包括HashMap中为什么重写equals还要重写hashcode、map的分类和常见情况、final关键字的用法、Synchronized和lock的区别、volatile的介绍、Syncronized锁的作用、构造函数和构造函数重载的概念、方法覆盖和方法重载的区别、反射获取和设置对象私有字段的值的方法、通过反射创建对象的方式以及内部类的详解。 ... [详细]
  • HashMap的相关问题及其底层数据结构和操作流程
    本文介绍了关于HashMap的相关问题,包括其底层数据结构、JDK1.7和JDK1.8的差异、红黑树的使用、扩容和树化的条件、退化为链表的情况、索引的计算方法、hashcode和hash()方法的作用、数组容量的选择、Put方法的流程以及并发问题下的操作。文章还提到了扩容死链和数据错乱的问题,并探讨了key的设计要求。对于对Java面试中的HashMap问题感兴趣的读者,本文将为您提供一些有用的技术和经验。 ... [详细]
  • Ihaveaworkfolderdirectory.我有一个工作文件夹目录。holderDir.glob(*)>holder[ProjectOne, ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了源码分析--ConcurrentHashMap与HashTable(JDK1.8)相关的知识,希望对你有一定的参考价值。  Concu ... [详细]
  • 查找给定字符串的所有不同回文子字符串原文:https://www ... [详细]
  • 796.[APIO2012]派遣在一个忍者的帮派里,一些忍者们被选中派遣给顾客,然后依据自己的工作获取报偿。在这个帮派里,有一名忍者被称之为Master。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文介绍了一道经典的状态压缩题目——关灯问题2,并提供了解决该问题的算法思路。通过使用二进制表示灯的状态,并枚举所有可能的状态,可以求解出最少按按钮的次数,从而将所有灯关掉。本文还对状压和位运算进行了解释,并指出了该方法的适用性和局限性。 ... [详细]
  • python中安装并使用redis相关的知识
    本文介绍了在python中安装并使用redis的相关知识,包括redis的数据缓存系统和支持的数据类型,以及在pycharm中安装redis模块和常用的字符串操作。 ... [详细]
author-avatar
常叽叽_655
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有