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

第二道线形基啊,开心

开题的时候以为要用tarjan缩一遍图,然后在新图上,跑出一条简单路径,再把每个新点扔进线形基,就可以了

码了80行忽然发现好像这样没法做,赶紧去上了个厕所冷静了一下,然后发现直接dfs就好了

废话一堆

首先,dfs整个图,用dis[]记录每个点的距离,vis[]记录是否到达过,若到达过证明是个环,扔进线形基里面就好了

最后查询输出即可

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=2e5+7;
int m,n,k,cnt,head[N];
ll dis[N];
struct xxj
{
    ll p[60];
    void insert(ll x)
    {
        for (int i=60;i>=0;i--)
        if (x&(1ll<<i))
        {
            if (!p[i]) {p[i]=x;break;} 
            else x^=p[i];
        }
    }
    ll query(ll x)
    {
        for (int i=60;i>=0;i--)
        x=max(x,x^p[i]);
        return x;
    }
} G;
struct edge
{
    int nx,to;
    ll dist;
} e[N];
void add_edge(int a,int b,ll dist)
{
    cnt++;e[cnt].to=b;e[cnt].nx=head[a];e[cnt].dist=dist;head[a]=cnt;
    cnt++;e[cnt].to=a;e[cnt].nx=head[b];e[cnt].dist=dist;head[b]=cnt;
}
bool vis[N];
void dfs(int x)
{
    vis[x]=true;
    for (int i=head[x];i;i=e[i].nx)
    {
        int y=e[i].to;
        if (!vis[y]) dis[y]=dis[x]^e[i].dist,dfs(y);
        else G.insert(dis[x]^dis[y]^e[i].dist);
    }
}
int main()
{
    freopen("xorr.in","r",stdin);
    freopen("xorr.out","w",stdout);
    scanf("%d%d",&n,&m);
    for (int i=1;i<=m;i++)
    {
        int x,y;
        ll z;
        scanf("%d%d%lld",&x,&y,&z);
        add_edge(x,y,z);
    }
    dfs(1);
    printf("%lld
",G.query(dis[n]));
    return 0;
}
慢即是快,细则是能,于小处铸迤逦
原文地址:https://www.cnblogs.com/Hale522520/p/10745478.html