bzoj2115 Xor
problem
考虑一个边权为非负整数的无向连通图,节点编号为\(1\) 到 \(N\),试求出一条从 \(1\) 号节点到 \(N\) 号节点的路径,使得路径上经过的边的权值的 \(XOR\) 和最大。
路径可以重复经过某些点或边,当一条边在路径中出现了多次时,其权值在计算 \(XOR\) 和时也要被计算相应多的次数,具体见样例。
solution
考虑先确定一条从\(1\)到\(n\)的不含环的路径。
如图,我们先选择\(1-2-3-4-9-10\)这条路径,然后发现,我们在3这个位置可以通过\(3-5\)这条边,去环里面转一圈,然后再回来。因为\(3-5\)这条边走了两边。所以增加的边权就是这个环的异或和。
这个我们就可以猜想了。我们先选择任意一个可以从\(1-n\)的路径,称之为链。然后该图中所有的环都是可以产生贡献的。所以我们把这条链的异或和和各个环的异或和全部扔到线性基里去。然后求最大值就行了。
为什么这条链可以任意选呢。因为如果有其他的路径可以到达\(n\),必定与该链形成了环。只要选择那个环就相当于走了另外一条路径。
如图
我们可以选择以\(1-2-3-4-9-10\)或者是\(1-2-3-4-11-12-13-9-10\)作为链。
不管以哪一条为链只要异或上这个蓝色的环。就会变成另外一条链。
code
/*
* @Author: wxyww
* @Date: 2019-07-23 14:59:35
* @Last Modified time: 2019-07-23 15:09:13
*/
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<ctime>
using namespace std;
typedef long long ll;
const int N = 100100;
#define int ll
ll read() {
ll x=0,f=1;char c=getchar();
while(c<'0'||c>'9') {
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9') {
x=x*10+c-'0';
c=getchar();
}
return x*f;
}
struct node {
int v,nxt;ll w;
}e[N << 1];
int head[N],ejs;
void add(int u,int v,int w) {
e[++ejs].v = v;e[ejs].w = w;e[ejs].nxt = head[u];head[u] = ejs;
}
int vis[N];
ll dis[N],p[N];
void ins(ll x) {
for(int i = 63;i >= 0;--i) {
if(!(x >> i & 1)) continue;
if(!p[i]) {
p[i] = x;break;
}
else x ^= p[i];
}
}
ll query(ll x) {
ll ans = x;
for(int i = 63;i >= 0;--i) if((ans ^ p[i]) > ans) ans ^= p[i];
return ans;
}
void dfs(int u,int father) {
vis[u] = 1;;
for(int i = head[u];i;i = e[i].nxt) {
int v = e[i].v;
if(v == father) continue;
if(vis[v]) {
ins(dis[u] ^ e[i].w ^ dis[v]);continue;
}
else dis[v] = dis[u] ^ e[i].w,dfs(v,u);
}
}
main() {
int n = read(),m = read();
for(int i = 1;i <= m;++i) {
int u = read(),v = read();ll w = read();
add(u,v,w);add(v,u,w);
}
dfs(1,0);
cout<<query(dis[n]);
return 0;
}
===================================================================================
该怎麼去形容为思念酝酿的痛
夜空霓虹都是我不要的繁荣 ===================================================================================