[WC 2011]Xor
Description

Input
第一行包含两个整数N和 M, 表示该无向图中点的数目与边的数目。 接下来M 行描述 M 条边,每行三个整数Si,Ti ,Di,表示 Si 与Ti之间存在 一条权值为 Di的无向边。 图中可能有重边或自环。
Output
仅包含一个整数,表示最大的XOR和(十进制结果),注意输出后加换行回车。
Sample Input
1 2 2
1 3 2
2 4 1
2 5 1
4 5 3
5 3 4
4 3 2
Sample Output
HINT

题解
我们考虑如何得到答案,首先所有的环都是可以经过的。这是为什么呢?
假设我们从$1$号点开始走,走到一个环的起点,然后我们经过这个环以后回到了环的起点,这时我们可以直接回到起点。这样,除了环上的路径,其他的路径都被抵消了。那么我们就只选了了这个环,也就是说,任意一个环都是可以选的。
然后我们先把所有的环都选出来,选入线性基中,再选出任意一条从$1$到$n$的路径,作为初始$ans$。初始$ans$异或线性基的最大值就是我们求的答案。为什么任意选一条路径也是可行的呢?
我们选了一条路径以后,如果存在一条更优的路径,那么这两条路径肯定是构成一个环的,会被选入线性基中。那么我们再用初始的$ans$异或一下这个环,我们就会发现,初始的$ans$被抵消了,二更优的那条路径留了下来。所以,我们选一个任意的初始$ans$是可行的。
于是这道题的实现就很明显了。先找出所有环,构成线性基,然后找出初始$ans$。这两步显然是可以$dfs$一遍一起搞的。然后用$ans$去异或线性基。从高位开始往低位异或。如果当前$ans$异或这一位的数能使$ans$变大,那么就异或。最终得到的$ans$就是我们要求的答案。
补充谈谈对取出环的异或值的理解:
我们记$d[u]$为从根节点,到$u$节点这条路径上的$xor$和,那么假设我们$dfs$拓展路径的时候,我们找到了以前一个访问过的点$v$,
那么这里就构成了一个环,且由于是$dfs$实现的,很容易知道$d[u]=d[v]⊕w_1⊕w_2⊕...$,$w$为边权。
我们记我们插入线性基的元素(环上的$xor$和)为$x$,$x=w_1⊕w_2⊕...⊕w_i$,
因为我们知道$a⊕a=0$,那么$x=d[u]⊕d[u]⊕w_1⊕w_2⊕...⊕w_i$$=d[u]⊕d[v]⊕w_i$($w_i$为$u->v$的边权)
//It is made by Awson on 2017.9.21
#include <set>
#include <map>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <string>
#include <cstdio>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define Min(a, b) ((a) < (b) ? (a) : (b))
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define LL long long
using namespace std;
const int N = ;
const int M = ;
LL st[]; int n, m, u, v;
LL c;
struct tt {
int to, next;
LL cost;
}edge[*M+];
int path[N+], top;
LL d[N+];
LL p[];
bool vis[N+]; LL getmax(LL x) {
for (int i = ; i >= ; i--)
if ((x^p[i]) > x)
x ^= p[i];
return x;
}
void insert(LL x) {
for (int i = ; i >= ; i--)
if (x&st[i]) {
if (!p[i]) {
p[i] = x;
break;
}
x ^= p[i];
}
}
void add(int u, int v, LL c) {
edge[++top].to = v;
edge[top].cost = c;
edge[top].next = path[u];
path[u] = top;
}
void dfs(int u) {
vis[u] = ;
for (int i = path[u]; i; i = edge[i].next) {
if (vis[edge[i].to]) insert(d[u]^d[edge[i].to]^edge[i].cost);
else {
d[edge[i].to] = d[u]^edge[i].cost;
dfs(edge[i].to);
}
}
}
void work() {
st[] = ;
for (int i = ; i < ; i++) st[i] = st[i-]<<;
for (int i = ; i <= m; i++) {
scanf("%d%d%lld", &u, &v, &c);
add(u, v, c); add(v, u, c);
}
dfs();
LL ans = getmax(d[n]);
printf("%lld\n", ans);
}
int main() {
while (~scanf("%d%d", &n, &m))
work();
return ;
}
[WC 2011]Xor的更多相关文章
- 【BZOJ 2115】【WC 2011】Xor
计算1到n的一条路径使得路径上的值xor和最大. 先任意走一条路径计算xor和,然后dfs的时候处理出所有的环的xor和,这样对于所有的环的xor和求线性基,在任意走出的路径的xor和上贪心即可. 正 ...
- [WC 2011]最大Xor和路径
题目大意: 给你一张n个点,m条边的无向图,每条边都有一个权值,求:1到n的路径权值和的最大值. 题解: 任意一条路径都能够由一条简单路径(任意一条),在接上若干个环构成(如果不与这条简单路径相连就走 ...
- [HNOI 2011]XOR和路径
Description 给定一个无向连通图,其节点编号为 1 到 N,其边的权值为非负整数.试求出一条从 1 号节点到 N 号节点的路径,使得该路径上经过的边的权值的“XOR 和”最大.该路径可以重复 ...
- CF724G 【Xor-matic Number of the Graph】
题目就不翻译了吧,应该写的很清楚了... 首先 \(,\) 不懂线性基的可以戳这里.知道了线性基\(,\) 但是从来没有写过线性基和图论相结合的\(,\) 可以戳这里. 好\(,\) 点完了这些前置技 ...
- zhengrui集训D1-D5笔记
Day_1 计数 它咕掉了 Day_1 序列数据结构 它咕掉了 Day_2 线性代数 高斯消元\Large{高斯消元}高斯消元 普通版:略 模质数:求逆 模合数:exgcd 逆矩阵\Large{逆矩阵 ...
- WC前的小计划
写在前面的.. 要去WC了好开心的呢.. 但是之前荒废了好多时间呢.. 好吧从明天开始加紧训练,目标是:WC前bzoj300t..(现在是260呢..) 开始吧 来看看完成情况: 40/40 [201 ...
- Linux之 sort,uniq,cut,wc命令详解
sort sort 命令对 File 参数指定的文件中的行排序,并将结果写到标准输出.如果 File 参数指定多个文件,那么 sort 命令将这些文件连接起来,并当作一个文件进行排序. sort语法 ...
- Ubuntu 14.10 下sort,uniq,cut,wc命令详解
sort sort 命令对 File 参数指定的文件中的行排序,并将结果写到标准输出.如果 File 参数指定多个文件,那么 sort 命令将这些文件连接起来,并当作一个文件进行排序. sort语法 ...
- 【待填坑】bzoj上WC的题解
之前在bzoj上做了几道WC的题目,现在整理一下 bzoj2115 去膜拜莫队的<高斯消元解xor方程组> bzoj2597 LCT维护MST bzoj1758 分数规划+树分治+单调队列 ...
随机推荐
- servlet3.0注解loadOnStartup不起作用解决方案
多次尝试3.0在源码中直接用注解配置loadOnStartup=1,即web应用启动时创建servlet实例,发现不起作用,但是在web.xml配置则可以正常运行.先上源码. package lee; ...
- eclipse配置svn方法
一.在Eclipse里下载Subclipse插件 方法一:从Eclipse Marketplace里面下载 具体操作:打开Eclipse --> Help --> Eclipse Mark ...
- 第四次团队作业:社团申请App
概要: 基于上次软件设计本着界面简洁.易于使用的初衷,进行功能的实现,代码位置:https://github.com/LinZezhong/testDemo 第一部分:软件的使用 注册: 登录: 主界 ...
- 关于移动web教程免费发布
各位老铁大家好,最近经历了太多太多,精力一直不能集中做自己愿意做的事情. 移动Web课程一开始设置收费10块,其实本意是让大家感觉有支出,就会相对珍惜好好学习,但是发现收费把大部分人挡在门外,现在恢复 ...
- Oracle数据库游标精解
游标 定义:标识结果集中数据行的一种容器(CURSOR),游标允许应用程序对查询语句返回的行结果集中的每一行进行相同或不同的操作,而不是一次对整个结果集进行同一种操作.实际上是一种能从包括多条数据记录 ...
- New UWP Community Toolkit - DropShadowPanel
概述 UWP Community Toolkit 中有一个为 Frmework Element 提供投影效果的控件 - DropShadowPanel,本篇我们结合代码详细讲解 DropShado ...
- 分布式版本控制系统Git的安装及使用
Git的安装分为客户端安装和服务端安装,鉴于我平时码代码在windows环境下,因此本文客户端安装直接在windows环境,服务端安装在linux环境下(centos). Git客户端安装 客户端下载 ...
- Python3 re模块(正则表达式)
一:什么是正则? 正则就是用一些具有特殊含义的符号组合到一起(称为正则表达式)来描述字符或者字符串的方法.或者说:正则就是用来描述一类事物的规则. (在Python中)它内嵌在Python中,并通过r ...
- tensorflow安装篇
安装虚拟机redhat7u4-64 镜像文件在http://www.linuxfly.org/post/659 更换yum 参考https://blog.csdn.net/xiaoyiaoyou/ar ...
- kafka和mqtt的区别是什么?
两者都是从传统的Pub/Sub消息系统演化出来的,但是进化方向不一样,比较如下: Kafka是为了数据集成的场景,与以往Pub/Sub消息总线不一样,通过分布式架构提供了海量消息处理.高容错的方式存储 ...