【bzoj2115】[Wc2011] Xor DFS树+高斯消元求线性基
题目描述

输入
第一行包含两个整数N和 M, 表示该无向图中点的数目与边的数目。 接下来M 行描述 M 条边,每行三个整数Si,Ti ,Di,表示 Si 与Ti之间存在 一条权值为 Di的无向边。 图中可能有重边或自环。
输出
仅包含一个整数,表示最大的XOR和(十进制结果),注意输出后加换行回车。
样例输入
5 7
1 2 2
1 3 2
2 4 1
2 5 1
4 5 3
5 3 4
4 3 2
样例输出
6
题解
DFS树+高斯消元求线性基
首先肯定能够想到,1->n的路径一定是一条链+选择经过某些环。
那么我们只需要处理出链和环的异或和就可以了。
我们使用DFS树预处理,这样每一条返祖边就对应着一个环。
求出所有环以后,要求最大值,我们需要先对环的异或值求一下线性基,然后再贪心处理即可。
#include <cstdio>
#include <algorithm>
#define N 50010
#define M 200010
using namespace std;
typedef long long ll;
int head[N] , to[M] , tag[M] , next[M] , cnt = 1 , vis[N] , deep[N] , num;
ll len[M] , dis[N] , a[M];
void add(int x , int y , ll z)
{
to[++cnt] = y , len[cnt] = z , next[cnt] = head[x] , head[x] = cnt;
}
void dfs(int x)
{
int i;
vis[x] = 1;
for(i = head[x] ; i ; i = next[i])
if(!vis[to[i]])
dis[to[i]] = dis[x] ^ len[i] , deep[to[i]] = deep[x] + 1 , tag[i] = tag[i ^ 1] = 1 , dfs(to[i]);
}
int main()
{
int n , m , i , j , x , y , tot = 0;
ll d , z , ans;
scanf("%d%d" , &n , &m);
for(i = 1 ; i <= m ; i ++ ) scanf("%d%d%lld" , &x , &y , &z) , add(x , y , z) , add(y , x , z);
dfs(1);
for(x = 1 ; x <= n ; x ++ )
for(i = head[x] ; i ; i = next[i])
if(!tag[i] && deep[to[i]] < deep[x])
a[++num] = dis[to[i]] ^ dis[x] ^ len[i];
for(d = 1ll << 62 ; d ; d >>= 1)
{
for(j = ++tot ; j <= num ; j ++ )
{
if(a[j] & d)
{
swap(a[j] , a[tot]);
break;
}
}
if(j > num)
{
tot -- ;
continue;
}
for(j = 1 ; j <= num ; j ++ )
if(j != tot && a[j] & d)
a[j] ^= a[tot];
}
ans = dis[n];
for(i = 1 ; i <= tot ; i ++ )
if((ans ^ a[i]) > ans)
ans ^= a[i];
printf("%lld\n" , ans);
return 0;
}
【bzoj2115】[Wc2011] Xor DFS树+高斯消元求线性基的更多相关文章
- 【bzoj4269】再见Xor 高斯消元求线性基
题目描述 给定N个数,你可以在这些数中任意选一些数出来,每个数可以选任意多次,试求出你能选出的数的异或和的最大值和严格次大值. 输入 第一行一个正整数N. 接下来一行N个非负整数. 输出 一行,包含两 ...
- HDU3949/AcWing210 XOR (高斯消元求线性基)
求第k小的异或和,用高斯消元求更简单一些. 1 //用高斯消元求线性基 2 #include<bits/stdc++.h> 3 using namespace std; 4 #define ...
- 【bzoj3105】[cqoi2013]新Nim游戏 高斯消元求线性基
题目描述 传统的Nim游戏是这样的:有一些火柴堆,每堆都有若干根火柴(不同堆的火柴数量可以不同).两个游戏者轮流操作,每次可以选一个火柴堆拿走若干根火柴.可以只拿一根,也可以拿走整堆火柴,但不能同时从 ...
- 【bzoj4004】[JLOI2015]装备购买 贪心+高斯消元求线性基
题目描述 脸哥最近在玩一款神奇的游戏,这个游戏里有 n 件装备,每件装备有 m 个属性,用向量zi(aj ,.....,am) 表示 (1 <= i <= n; 1 <= j < ...
- 【BZOJ2115】[Wc2011] Xor 高斯消元求线性基+DFS
[BZOJ2115][Wc2011] Xor Description Input 第一行包含两个整数N和 M, 表示该无向图中点的数目与边的数目. 接下来M 行描述 M 条边,每行三个整数Si,Ti ...
- 【BZOJ2322】[BeiJing2011]梦想封印 高斯消元求线性基+DFS+set
[BZOJ2322][BeiJing2011]梦想封印 Description 渐渐地,Magic Land上的人们对那座岛屿上的各种现象有了深入的了解. 为了分析一种奇特的称为梦想封印(Fantas ...
- 【BZOJ2460】[BeiJing2011]元素 贪心+高斯消元求线性基
[BZOJ2460][BeiJing2011]元素 Description 相传,在远古时期,位于西方大陆的 Magic Land 上,人们已经掌握了用魔法矿石炼制法杖的技术.那时人们就认识到,一个法 ...
- 【BZOJ2844】albus就是要第一个出场 高斯消元求线性基
[BZOJ2844]albus就是要第一个出场 Description 已知一个长度为n的正整数序列A(下标从1开始), 令 S = { x | 1 <= x <= n }, S 的幂集2 ...
- BZOJ 4269 高斯消元求线性基
思路: 最大: 所有线性基异或一下 次大: 最大的异或一下最小的线性基 搞定~ //By SiriusRen #include <cstdio> #include <algorith ...
随机推荐
- 洛谷 P1880 石子合并
题目描述 在一个圆形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分. 试设计出1个算法,计算出将N堆石子合并成1 ...
- java入门第二章——java编程基础
习题 一.填空题 (p)1.java中的程序代码都必须在一个类中定义,类使用(class)关键字来定义. (p)2.布尔常量即布尔类型的两个值,分别是(true)和(false) (p18)3.jav ...
- 5分钟部署一个Hello World Servlet到CloudFoundry
首先从我的Github下载我写好的hello world Servlet到本地. 安装Maven,然后执行命令行mvn clean install,确保build成功,在项目根目录的target文件夹 ...
- ABAP vs Java, 蛙泳 vs 自由泳
去年7月定下的一年之内学会自由泳的目标终于实现了,特来还愿. ABAP和Java, 蛙泳和自由泳.前面的组合是Jerry用来挣钱养家的技术,后者是Jerry花了大量业余时间和金钱苦练的技能.或许有的朋 ...
- Android(java)学习笔记122:BroadcastReceiver之 有序广播和无序广播(BroadcastReceiver优先级)
之前我们在Android(java)学习笔记178中自定义的广播是无序广播,下面我们要了解一下有序广播: 1. 我们首先了解一下有序广播和无序广播区别和联系? (1)有序广播> 接受者有优先级, ...
- python_101_类方法
class Dog(object): n=333 name='小虎子' def __init__(self,name): self.name=name @classmethod def eat(sel ...
- UIPopoverController
if (popOver == nil) { popOver = [[UIPopoverController alloc] initWithContentViewController:viewVC]; ...
- 【Python项目实战】Pandas:让你像写SQL一样做数据分析(一)
1. 引言 Pandas是一个开源的Python数据分析库.Pandas把结构化数据分为了三类: Series,1维序列,可视作为没有column名的.只有一个column的DataFrame: Da ...
- 单行代码实现xml转换成数组
$string = '<xml> <return_code><![CDATA[SUCCESS]]></return_code> <return_m ...
- C++图书馆管理系统项目中部分功能代码实现(书籍推荐)
bool UserServiceImpl::Compare1(Book b1,Book b2)//按照借阅次数比较{ if(b1.GetCnt() > b2.GetCnt()) { return ...