P4151 [WC2011]最大XOR和路径

这道题啊,精妙。

第一会发现环是想走就走的。因此需要找到环,然后把环的异或值加入线性基。

再者发现只要将刚开始的 链的异或 在线性基里找到最大值就行。但是这条链是需要去寻找的吗?发现并不需要,因为可以发现如果有别的路径,那么两条路径就必定会产生一个环,那么在线性基里就可以通过异或(想当于改变初始认定的环)就行了。

代码

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
const int N=1e6;
struct edge{
	ll to,w,ne;
}e[N];
int cnt;
int head[N];
ll g[61];
void add(ll x){
	for(int i=60;i>=0;i--)if((x>>i)&1){
		if(!g[i]){
			g[i]=x;
			break;
		}
		x^=g[i];
	}
}
ll s_max(ll ean){
	for(int i=60;i>=0;i--){
		ean=max(ean,ean^g[i]);
	}
	return ean;
}
void init(){
	memset(head,-1,sizeof head);
}
void addedge(ll a,ll b,ll w){
	e[cnt].to=b;
	e[cnt].w=w;
	e[cnt].ne=head[a];
	head[a]=cnt++;
}
ll pre[N];
ll vis[N];
void dfs(int x,ll res){
	pre[x]=res;
	for(int i=head[x];~i;i=e[i].ne){
		int u=e[i].to;
		if(!vis[u]){
			vis[u]=1;
			dfs(u,res^e[i].w);
		}else{
			add(res^e[i].w^pre[e[i].to]);
		}
	}
}

int main(){
	init();
	int n,m;
	cin>>n>>m;
	for(int i=0;i<m;i++){
		int x,y;ll w;
		cin>>x>>y>>w;
		addedge(x,y,w);
		addedge(y,x,w);
	}
	dfs(1,0);
	cout<<s_max(pre[n])<<endl;
}

  

posted @ 2020-07-27 22:39  Ean1zhi  阅读(131)  评论(1编辑  收藏  举报