bzoj2115 [ WC2011 ] -- 线性基

如果从点 i 走到某个环上的点j,绕环一圈,再走回来,那么从 i 走到j的路径就被抵消了。相当于只走了环上的点。那么答案就是一条 1 n的路径与若干个环的异或和的最大值,线性基即可。

代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 100010
#define M 63
#define ll long long
struct Edge{
    int t,nx;
    ll w;
}e[N<<1];
ll a[M],z,Ans,d[N];
int i,j,k,n,m,t,h[N],x,y,Cnt;
bool b[N];
inline void Add(int x,int y,ll z){
    e[++Cnt].t=y;e[Cnt].nx=h[x];e[Cnt].w=z;h[x]=Cnt;
}
inline void Insert(ll x){
    for(int i=M-1;i;i--)
    if((x>>i-1)&1)
    if(!a[i]){
        a[i]=x;
        break;
    }else x^=a[i];
}
inline void Dfs(int x){
    b[x]=1;
    for(int i=h[x];i;i=e[i].nx){
        if(!b[e[i].t])d[e[i].t]=d[x]^e[i].w,Dfs(e[i].t);else
        Insert(d[e[i].t]^d[x]^e[i].w);
    }
}
int main(){
    scanf("%d%d",&n,&m);
    for(i=1;i<=m;i++)scanf("%d%d%lld",&x,&y,&z),Add(x,y,z),Add(y,x,z);
    Dfs(1);
    for(Ans=d[n],i=M-1;i;i--)
    if((a[i]^Ans)>Ans)Ans^=a[i];
    printf("%lld\n",Ans);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值