热门标签 | 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;
}

推荐阅读
  • 题目链接:POJ 2777。问题描述:给定一个区域,需要进行多次涂色操作,并在每次操作后查询某个区间内的不同颜色数量。解决方案:由于题目中颜色种类不超过30种,可以利用线段树的懒惰更新策略来高效处理这些操作。通过懒惰标记,避免了不必要的节点更新,从而显著提高了算法的效率。此外,该方法还能有效应对大规模数据输入,确保在合理的时间内完成所有操作。 ... [详细]
  • 每日精选Codeforces训练题:1119E(贪心算法)、821C(栈模拟)和645D(拓扑排序)
    题目涉及三种不同类型的算法问题:1119E(贪心算法)、821C(栈模拟)和645D(拓扑排序)。其中,1119E的问题背景是有n种不同长度的棍子,长度分别为2^0, 2^1, …, 2^(n-1),每种棍子的数量为a[i]。任务是计算可以组成的三角形数量。根据三角形的性质,任意两边之和必须大于第三边。该问题可以通过贪心算法高效解决,通过合理选择棍子组合来最大化三角形的数量。 ... [详细]
  • 在2021-2022 ACM集训队月度编程挑战赛第二轮中,题目“最大值与最小值的选择”要求参赛者处理一个包含n个元素的数组,并给定一个整数k。任务是通过选择特定的子数组,计算并返回这些子数组的最大值和最小值之间的差值。该问题考验了选手对数组操作和优化算法的理解与应用能力。 ... [详细]
  • 题目:图像处理(HDU1828,计算周长并集,利用线段树与离散化技术进行扫描) ... [详细]
  • 在HDU 1166敌军布阵问题中,通过运用线段树数据结构,可以高效地计算指定区间的敌军数量。该算法不仅能够在限定的时间和内存条件下快速求解,还能够灵活应对动态变化的战场局势,为实时决策提供支持。 ... [详细]
  • 在晴朗天气条件下,对一种神奇的魔法现象进行了深入分析。该题目为原创,基准时间限制为1秒,空间限制为131072KB,分值20,属于3级难度的算法题。研究发现,这种魔法现象在阳光明媚的环境中表现得尤为显著,进一步探讨了其背后的科学原理和技术实现方法。 ... [详细]
  • 开发心得:成为SGU475智能筏工的策略与技巧 ... [详细]
  • 本文详细解析了九度编程平台上的斐波那契数列高效算法挑战(题目编号:1387)。该挑战要求在1秒的时间限制和32兆的内存限制下,设计出高效的斐波那契数列计算方法。通过多种算法的对比和性能分析,本文提供了优化方案,帮助参赛者在限定资源条件下实现高效计算。 ... [详细]
  • 如何利用正则表达式(regexp)实现高效的模式匹配?本文探讨了正则表达式在编程中的应用,并分析了一个示例程序中存在的问题。通过具体的代码示例,指出该程序在定义和使用正则表达式时的不当之处,旨在帮助读者更好地理解和应用正则表达式技术。 ... [详细]
  • 利用 Spring BeanUtils 实现 JavaBean 的深度克隆与属性复制 ... [详细]
  • 题目链接:http://codeforces.com/gym/101190/attachments题意:在一个共享三轮车站点,某些用户需要租用车辆。该问题涉及如何通过离线查询和排序优化策略来高效地管理和分配车辆资源。具体来说,需要设计一种算法,在满足所有用户需求的同时,最小化总等待时间和资源浪费。通过合理的数据结构和算法优化,可以显著提高系统的整体性能和用户体验。 ... [详细]
  • 如何高效启动大数据应用之旅?
    在前一篇文章中,我探讨了大数据的定义及其与数据挖掘的区别。本文将重点介绍如何高效启动大数据应用项目,涵盖关键步骤和最佳实践,帮助读者快速踏上大数据之旅。 ... [详细]
  • 在处理遗留数据库的映射时,反向工程是一个重要的初始步骤。由于实体模式已经在数据库系统中存在,Hibernate 提供了自动化工具来简化这一过程,帮助开发人员快速生成持久化类和映射文件。通过反向工程,可以显著提高开发效率并减少手动配置的错误。此外,该工具还支持对现有数据库结构进行分析,自动生成符合 Hibernate 规范的配置文件,从而加速项目的启动和开发周期。 ... [详细]
  • 如何在 Node.js 环境中将 CSV 数据转换为标准的 JSON 文件格式? ... [详细]
  • 本文详细探讨了OpenCV中人脸检测算法的实现原理与代码结构。通过分析核心函数和关键步骤,揭示了OpenCV如何高效地进行人脸检测。文章不仅提供了代码示例,还深入解释了算法背后的数学模型和优化技巧,为开发者提供了全面的理解和实用的参考。 ... [详细]
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社区 版权所有