【ybt金牌导航8-1-4】【luogu P4151】路径最大异或和 / 最大XOR和路径

路径最大异或和 / 最大XOR和路径

题目链接:ybt金牌导航8-1-4 / luogu P4151

题目大意

给你一个无向图,边有边权,要你找一条从 1 到 n 的路径,使得路径上经过的边边权异或起来最大。
如果重复经过边,那边权要异或多次。

思路

首先我们想想没有环怎么搞。
那容易 DP 一下得到 disi(从 1i 的路径异或和),那答案就是 disn

但你想到它有环。
那假设这些环都不在 1n 的最短路径上。
那我们就可以选择专门去经过这个环或不经过,根据异或有贡献分别是环边的异或和以及 0

那如果在路径上呢?
在这里插入图片描述
红色是你选的一个路径,然后粉色是在路径上的一个环。
那你把它们异或起来,你就发现,它就变成了这个:
在这里插入图片描述
棕色的那个,就是另一条路径了,那我们可以根据要不要一个这个环来改变要走的路径。

那接着有人会问,可能两个小环会组成大环,你要把所有的环都找出来,不也会超时吗?
那我们再画图来看:
在这里插入图片描述
红色是两个小环,粉色是大环。
那你发现,你把两个小环异或起来,就是你要的大环了。
那我们其实可以通过小环的组合异或,得到所有的环。

那问题就变成了给你一堆数,有一个数一定要选(你找的随便一个从 1n 的路径),其它的任选一些(小环),要选出的数的异或值最大。
那就是线性基搞搞就好了。

代码

#include<cstdio> #define ll long long using namespace std; struct node { ll x; int to, nxt; }e[200001]; int n, m, le[50001], x, y, KK; ll z, dis[50001], p[101]; bool in[50001]; void add(int x, int y, ll z) { e[++KK] = (node){z, y, le[x]}; le[x] = KK; e[++KK] = (node){z, x, le[y]}; le[y] = KK; } //线性基 void xxj_add(ll x) { for (int i = 60; i >= 0; i--) if ((x >> i) & 1) { if (!p[i]) { p[i] = x; break; } x ^= p[i]; } } //dfs void dfs(int now, int father) { in[now] = 1; for (int i = le[now]; i; i = e[i].nxt) if (!in[e[i].to]) {//正常跑 dis[e[i].to] = dis[now] ^ e[i].x; dfs(e[i].to, now); } else {//形成了环 xxj_add(dis[now] ^ dis[e[i].to] ^ e[i].x); } } ll get_max(ll re) {//线性基求最大值 for (int i = 60; i >= 0; i--) if (!((re >> i) & 1)) if (p[i]) re ^= p[i]; return re; } int main() { scanf("%d %d", &n, &m); for (int i = 1; i <= m; i++) { scanf("%d %d %lld", &x, &y, &z); add(x, y, z); } dfs(1, 0); printf("%lld", get_max(dis[n])); return 0; }

__EOF__

本文作者あおいSakura
本文链接https://www.cnblogs.com/Sakura-TJH/p/YBT_JPDH_8-1-4.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   あおいSakura  阅读(40)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示