Description

给定一个无向连通图,边有边权,求一个 \(1~\sim n\) 的路径,最大化边权的异或和。如果一条边经过多次则计算多次。

Input

第一行是两个整数 \(n,m\) 代表点数和边数

下面 \(m\) 行每行三个整数描述一条边

Output

输出一行一个整数代表答案

Hint

\(1~\leq~n~\leq~50000,1~\leq~m~\leq~100000,1~\leq~\) 边权 \(\leq~10^{18}\)

Solution

首先注意到一个结论:对于所有的简单环,环上边权的异或和都可以无代价的获取。原因是可以从一号点出发进入该环绕一圈后原路返回。由于一条路径绕两边对答案的贡献为 \(0\) ,所以这些简单环的异或和都可以无代价取得。那么现在问题就转化成了寻找一条 \(1\) 到 \(n\) 的路径,再异或上一些简单环的异或和,最大化答案。

我们考虑应该寻找哪一条路径:事实上任选一条路径即可。原因是选择的路径和答案路径一定可以构成一个环,所以异或上该环的权值就可以得到最优解。

考虑最大化异或和可以使用线性基解决。时间复杂度 \(O(m~+~n~\log^2d)\),其中 \(d\) 为边权

Code

#include <cstdio>
#include <algorithm>
#ifdef ONLINE_JUDGE
#define freopen(a, b, c)
#define printtime()
#else
#include <ctime>
#define printtime() printf("Times used = %ld ms\n", clock())
#endif
#define ci const int
#define cl const long long typedef long long int ll; namespace IPT {
const int L = 1000000;
char buf[L], *front=buf, *end=buf;
char GetChar() {
if (front == end) {
end = buf + fread(front = buf, 1, L, stdin);
if (front == end) return -1;
}
return *(front++);
}
} template <typename T>
inline void qr(T &x) {
char ch = IPT::GetChar(), lst = ' ';
while ((ch > '9') || (ch < '0')) lst = ch, ch=IPT::GetChar();
while ((ch >= '0') && (ch <= '9')) x = (x << 1) + (x << 3) + (ch ^ 48), ch = IPT::GetChar();
if (lst == '-') x = -x;
} template <typename T>
inline void ReadDb(T &x) {
char ch = IPT::GetChar(), lst = ' ';
while ((ch > '9') || (ch < '0')) lst = ch, ch = IPT::GetChar();
while ((ch >= '0') && (ch <= '9')) x = x * 10 + (ch ^ 48), ch = IPT::GetChar();
if (ch == '.') {
ch = IPT::GetChar();
double base = 1;
while ((ch >= '0') && (ch <= '9')) x += (ch ^ 48) * ((base *= 0.1)), ch = IPT::GetChar();
}
if (lst == '-') x = -x;
} namespace OPT {
char buf[120];
} template <typename T>
inline void qw(T x, const char aft, const bool pt) {
if (x < 0) {x = -x, putchar('-');}
int top=0;
do {OPT::buf[++top] = static_cast<char>(x % 10 + '0');} while (x /= 10);
while (top) putchar(OPT::buf[top--]);
if (pt) putchar(aft);
} const int maxn = 50010;
const int maxm = 200010;
const int maxl = 61; struct Edge {
int to;
ll v;
Edge *nxt;
};
Edge edge[maxm], *hd[maxn]; int ecnt;
inline void cont(ci from, ci to, cl v) {
Edge &e = edge[++ecnt];
e.to = to; e.nxt = hd[from]; e.v = v; hd[from] = &e;
} int n, m;
ll ans;
bool vis[maxn];
ll val[maxn], lb[maxl]; void reading();
void insert(ll);
void dfs(ci, cl); int main() {
freopen("1.in", "r", stdin);
qr(n); qr(m);
reading();
dfs(1, 0);
for (int i = maxl - 1; ~i; --i) {
ans = std::max(ans, ans ^ lb[i]);
}
qw(ans, '\n', true);
printtime();
return 0;
} void reading() {
int a, b; ll c;
for (int i = 1; i <= m; ++i) {
a = 0; b = 0; c = 0; qr(a); qr(b); qr(c);
cont(a, b, c); cont(b, a, c);
}
} void dfs(ci u, cl tp) {
vis[u] = true; val[u] = tp;
if (u == n) ans = tp;
for (Edge *e = hd[u]; e; e = e->nxt) {
int to = e->to;
if (!vis[to]) dfs(to, tp ^ e->v);
else insert(tp ^ e->v ^ val[to]);
}
} void insert(ll x) {
for (int i = maxl - 1; ~i; --i) if (x & (1ll << i)) {
if (lb[i]) {
x ^= lb[i];
} else {
lb[i] = x;
for (int j = maxl - 1; j > i; --j) if (lb[j]) {
lb[j] ^= x;
}
for (int j = 0; j < i; ++j) if (lb[j] & (1ll << i)) {
lb[i] ^= lb[j];
}
break;
}
}
}

【线性基/神仙题】P4151 [WC2011]最大XOR和路径的更多相关文章

  1. 洛谷 P4151 [WC2011]最大XOR和路径 解题报告

    P4151 [WC2011]最大XOR和路径 题意 求无向带权图的最大异或路径 范围 思路还是很厉害的,上午想了好一会儿都不知道怎么做 先随便求出一颗生成树,然后每条返祖边都可以出现一个环,从的路径上 ...

  2. P4151 [WC2011]最大XOR和路径

    P4151 [WC2011]最大XOR和路径 一道妙极了的题. 首先直接从1走到n 然后现在图上有很多环 所以可以在走到n之后走到环上一个点,再走一遍环,再原路返回.这样就会xor上环的权值. 然后只 ...

  3. 洛谷P4151 [WC2011] 最大XOR和路径 [线性基,DFS]

    题目传送门 最大XOR和路径 格式难调,题面就不放了. 分析: 一道需要深刻理解线性基的题目. 好久没打过线性基的题了,一开始看到这题还是有点蒙逼的,想了几种方法全被否定了.还是看了大佬的题解才会做的 ...

  4. 洛谷P4151 [WC2011]最大XOR和路径(线性基)

    传送门 不知道线性基是什么东西的可以看看蒟蒻的总结 首先看到异或就想到线性基 我们考虑有一条路径,那么从这条路径走到图中的任意一个环再走回这条路径上,对答案的贡献是这个环的异或和,走到这个环上的路径对 ...

  5. [洛谷P4151][WC2011]最大XOR和路径

    题目大意:给你一张$n$个点$m$条边的无向图,求一条$1->n$的路径,使得经过路径值的异或值最大(重复经过重复计算) 题解:某条路$k$被重复走了两次,那么它的权值对答案的贡献就是$0$,但 ...

  6. P4151 [WC2011]最大XOR和路径 线性基

    题目传送门 题意:给出一幅无向图,求1到n的所有路径中最大异或和,一条边可以被重复经过. 思路: 参考了大佬的博客 #pragma GCC optimize (2) #pragma G++ optim ...

  7. [WC2011]最大XOR和路径(线性基)

    P4151 [WC2011]最大XOR和路径 题目描述 XOR(异或)是一种二元逻辑运算,其运算结果当且仅当两个输入的布尔值不相等时才为真,否则为假. XOR 运算的真值表如下( 1 表示真, 0 表 ...

  8. [WC2011]最大XOR和路径 线性基

    [WC2011]最大XOR和路径 LG传送门 需要充分发掘经过路径的性质:首先注意不一定是简单路径,但由于统计的是异或值,重复走是不会被统计到的,考虑对于任意一条从\(1\)到\(n\)的路径的有效部 ...

  9. 题解-[WC2011]最大XOR和路径

    [WC2011]最大XOR和路径 给一个 \(n\) 个点 \(m\) 条边(权值为 \(d_i\))的无向有权图,可能有重边和子环.可以多次经过一条边,求 \(1\to n\) 的路径的最大边权异或 ...

随机推荐

  1. Docker Zero Deployment and Secrets (二)

    一. 健康检测: (1)定义检测信息如下(案例,在Dockerfile中定义) FROM alpine:3.6 ... HEALTHCHECK --interval=30s \     --timeo ...

  2. 微软职位内部推荐-SW Engineer II for Enterprise Platform

    微软近期Open的职位: Job posting title: SDE II Location: China, Beijing Group Overview Discovery & Colla ...

  3. DebuggerVisualizer时,序列化引出的问题。

    实现如下功能:http://www.cnblogs.com/devil0153/archive/2010/09/01/Visual-Studio-Custom-Debugger.html#288924 ...

  4. 慢吞吞的pip切换源

    http://blog.csdn.net/gz_liuyun/article/details/52778198

  5. maven实战读书笔记(一)

    环境变量设置 MAVEN_HOME:G:\maven-3.2\apache-maven-3.2.5 Path: G:\maven-3.2\apache-maven-3.2.5\bin 其实正确的设置应 ...

  6. (第七周)评论alpha发布

    本人所在组:奋斗吧兄弟 按课上展示组的顺序对其他组进行点评: 1.  新蜂 项目:游戏俄罗斯方块 界面完善,已经实现了游戏的基本功能.可以对图形进行变换形状,进行位置移动,可以加快下落的速度,并对一整 ...

  7. Daily Scrum 11.7

    明后两天周六日,按照TFS的日常安排应该是休息,所以让他们自由完成已经分配的任务. 姓名 今日任务 黄新越 提取爬取网页的关键字并输出到接口 刘垚鹏 程序总架构的修改与多线程的学习 王骜 多线程学习 ...

  8. [buaa-SE-2017]个人作业-期末总结

    个人作业-期末总结 Part1: 阅读作业 在这一部分,首先我将说说我对这次阅读作业中每篇文章的理解,最后结合这次团队项目的经理谈谈自己对软件开发的看法. 1. No Silver Bullet 文章 ...

  9. 基于GUI的小学生四则运算系统

    前言:首先在此感谢我的结对搭档,没有她的帮助和引导绝不会有现在的项目.很高兴和她一起结对完成这个项目.搭档真的是棒棒哒! 一.Coding.Net项目地址: https://git.coding.ne ...

  10. 由RS-232串口到PROFIBUS-DP总线的转换接口设计

    转自:http://gongkong.ofweek.com/2013-08/ART-310007-11001-28716256_2.html 1.PROFIBUS-DP网络协议 PROFIBUS的网络 ...