P4151 [WC2011]最大XOR和路径

题意:

给定一个无向连通图包含 n 个点 和 m 条边,每条边有边权,现在让你求一条 从点 1 到 n 的路径,使得路径上的边权异或和最大。(可能有边重边和自环,任意边可以重复走,没有限制)

分析:

首先根据异或的性质,一条边 或 一个环 走偶数遍的异或和 都是 0 ,所以对于一个环,要么不走,要么只走一遍,那么可以构想出最优路径一定是一条从 1 到 n 的 链 上套着 若干环,那么我们把每个环的异或和加进线性基,用这条链的异或和去 异或 线性基找到最大值就可以了,可是这个最优解的链怎么找呢,其实只要任意找一条从 1 到 n 的链就可以了,因为若存在两条从 1 到 n 的链,则它们已经构成了一个环,无论你选择哪一条作为基链,异或上这个环都会得到另一条链的异或和,所以就不用担心最优解的正确性了。

代码:
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;

typedef long long LL;
const int N = 5E4+10;

struct L_B{
	LL d[61],p[61];
	int cnt;
	L_B(){
		memset(d,0,sizeof(d));
		memset(p,0,sizeof(p));
		cnt=0;
	}
	bool insert(LL val){
		for(int i=60;i>=0;i--){
			if(val&(1LL<<i)){
				if(!d[i]){
					d[i]=val;
					break;
				}
				val^=d[i];
			}
		}
		return val>0;
    }
    LL query(LL res){
    	for(int i=60;i>=0;i--)
    		if((res^d[i])>res)
    			res^=d[i];
        return res;
	}
}H;

int n,m;

struct node{
	int to,nxt;LL w;
}e[N*4];
int head[N],tot=0;

void add(int u,int v,LL w){
	e[++tot].to=v;
	e[tot].w=w;
	e[tot].nxt=head[u];
	head[u]=tot;
}

LL dis[N];
bool vis[N];

void dfs(int u,int pre,LL res){
	dis[u]=res,vis[u]=1;
	for(int i=head[u];i;i=e[i].nxt){
		int v=e[i].to;LL w=e[i].w;
		if(v==pre) continue;
		if(vis[v]) H.insert(dis[u]^w^dis[v]);
		else dfs(v,u,res^w);
	}
}

int main()
{
	H=L_B();
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++){
		int u,v; LL w;
		scanf("%d%d%lld",&u,&v,&w);
		add(u,v,w);
		add(v,u,w);
    }
	dfs(1,0,0LL);
	printf("%lld",H.query(dis[n]));
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值