【BZOJ2115】Xor,第一次的线性基

Time:2016.08.26
Author:xiaoyimi
转载注明出处谢谢


传送门
思路:
权值就是一条单路径(1->n)+所有环
dfs把它们求出来就可以了
复杂度 O(n+m)
求出线性基,里面存储的就是各个环的xor值
后对每一位贪心就可以了
复杂度 O(64log(n+m))
代码:

#include<cstdio>
#include<iostream>
#include<cstring>
#define LL long long
using namespace std;
int n,m,cnt,tot;
int first[50005];
bool vis[50005];
LL data[1000005],lb[65],dis[50005],ans;
struct edge{
    int u,v,next;
    LL w;
}e[200005];
LL in()
{
    char ch=getchar();LL t=0;
    while (ch<'0'||ch>'9') ch=getchar();
    while (ch>='0'&&ch<='9') t=(t<<3)+(t<<1)+ch-48,ch=getchar();
    return t;
}
void add(LL z,int y,int x)
{
    e[++tot]=(edge){x,y,first[x],z};first[x]=tot;
    e[++tot]=(edge){y,x,first[y],z};first[y]=tot;
}
void dfs(int x)
{
    vis[x]=1;
    for (int i=first[x];i;i=e[i].next)
        if (!vis[e[i].v])
            dis[e[i].v]=dis[x]^e[i].w,
            dfs(e[i].v);
        else
            data[++cnt]=dis[x]^dis[e[i].v]^e[i].w,
            cnt-=(!data[cnt]);
}
main()
{
    n=in();m=in();
    for (int i=1;i<=m;++i)
        add(in(),in(),in());
    dfs(1);
    for (int i=1;i<=cnt;++i)
        for (int j=63;j>=0;--j)
            if (data[i]>>j&1)
                if (!lb[j]) 
                    {lb[j]=data[i];break;}
                else
                    data[i]^=lb[j];
    ans=dis[n];
    for (int i=63;i>=0;--i)
        if (!(ans>>i&1)) ans^=lb[i];
    printf("%lld\n",ans);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值