[luogu4151 WC2011] 最大XOR和路径 (线性基)

传送门

输入输出样例

输入样例#1:

5 7
1 2 2
1 3 2
2 4 1
2 5 1
4 5 3
5 3 4
4 3 2

输出样例#1:

6

说明

【样例说明】

根据异或的性质,将一个数异或两次便会消除影响
那么预处理所有环插入线性基中,之后随便(因为能够消除影响)找一条简单路径查询最大值即可

code:

//By Menteur_Hxy
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#define LL long long
#define M(a,b) memset(a,(b),sizeof(a))
#define F(i,a,b) for(register int i=(a);i<=(b);i++)
#define C(i,a,b) for(register int i=(b);i>=(a);i--)
#define E(i,u) for(register int i=head[u];i;i=nxt[i])
using namespace std;

LL rd() {
    LL x=0,fla=1; char c=getchar();
    while(!isdigit(c)) {if(c=='-') fla=-fla;c=getchar();}
    while(isdigit(c)) x=(x<<3)+(x<<1)+c-48,c=getchar();
    return x*fla;
}

const int N= 50010, M= 100010;
int n,m,ecnt;
int head[N],vis[N]; LL di[N];
int nxt[M<<1],to[M<<1]; LL dis[M<<1];
#define add(a,b,c) nxt[++ecnt]=head[a],to[ecnt]=b,head[a]=ecnt,dis[ecnt]=c

LL ba[70];
void insert(LL x) {
    for(int i=60;i>=0;i--) if(x>>i&1) {
        if(ba[i]) x^=ba[i];
        else {ba[i]=x;break;}
    }
}

LL query(LL x) {
    for(int i=60;i>=0;i--) if((x^ba[i])>x) x^=ba[i];
    return x;
}

void dfs(int u) {
    vis[u]=1;
    E(i,u) { int v=to[i];
        if(vis[v]) insert(di[u]^di[v]^dis[i]);
        else di[v]=di[u]^dis[i],dfs(v);
    }
    
}	

int main() {
    n=rd(); m=rd();
    F(i,1,m) {
        int a=rd(),b=rd(); LL c=rd();
        add(a,b,c); add(b,a,c);
    }
    dfs(1);
    printf("%lld",query(di[n]));
    return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。 博主:https://www.cnblogs.com/Menteur-Hxy/
原文地址:https://www.cnblogs.com/Menteur-Hxy/p/9263371.html