[WC2011]最大XOR和路径

我们首先给出结论:
我们随便找一颗生成树
把单元环拉进线性基。
单元环定义为:仅由一条非树边构成的环。
我们可以证明任意大环一定都一个或多个环的点集异或。
读者可以自己画图证明一下。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define LL long long
LL num[70];
bool insert(LL x) {
    for (int i=63;i>=0;i--)
        if ((x>>i)&1) {
            if (!num[i]) {
                num[i]=x;
                return true;
            }
            x^=num[i];
        }
    return false;
}
LL query(LL x) {
    LL res=x;
    for (int i=63;i>=0;i--)
        if ((res^num[i])>res)
            res^=num[i];
    return res;
}
struct edge {
    int to,next;
    LL w;
}e[200010];
int head[50010],ecnt;
inline void adde(int from,int to,LL w) {
    e[++ecnt]=(edge){to,head[from],w},head[from]=ecnt;
    e[++ecnt]=(edge){from,head[to],w},head[to]=ecnt;
}
int vis[50010];LL del[50010];
void dfs(int u,LL res) {
    del[u]=res,vis[u]=1;
    for (int i=head[u];i;i=e[i].next)
        if (!vis[e[i].to]) dfs(e[i].to,res^e[i].w);
        else insert(res^e[i].w^del[e[i].to]);
}
int main() {
    int n,m,a,b;LL c;scanf("%d%d",&n,&m);
    for (int i=1;i<=m;i++) scanf("%d%d%lld",&a,&b,&c),adde(a,b,c);
    dfs(1,0);
    printf("%lld\n",query(del[n]));
}
上一篇:两个数组最小的异或值之和


下一篇:findKey