BZOJ2115: [Wc2011] Xor

来源:互联网 发布:蓝牙 音乐软件 编辑:程序博客网 时间:2024/06/05 06:15

Description

Input

第一行包含两个整数N和 M, 表示该无向图中点的数目与边的数目。 接下来M 行描述 M 条边,每行三个整数Si,Ti ,Di,表示 Si 与Ti之间存在 一条权值为 Di的无向边。 图中可能有重边或自环。

Output

仅包含一个整数,表示最大的XOR和(十进制结果),注意输出后加换行回车。

Sample Input

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

Sample Output

6

HINT

Source

线性基
首先建一棵生成树 求出dis[T]把它塞进线性基 每次算答案它为基数
然后考虑所有非树边 设为(u,v) 则把dis[u]^dis[v]^val塞进去
正确性显然
#include<bits/stdc++.h> using namespace std; const int maxn=66666; int n,m,cnt; struct base{    long long a[61];    base()    {        for(int i=0;i<=60;i++)            a[i]=0;    }    void add(long long x)    {        for(int i=60;i>=0;i--)        {            if((x>>i)&1)            {                if(!a[i])                {                    a[i]=x;                    break;                }                    x^=a[i];            }        }    }    long long result(long long x)    {        for(int i=60;i>=0;i--)        {            if(!((x>>i)&1))            {                x^=a[i];            }        }        return x;    }}ans; struct Edge{    int u,v;    long long w;}edge[maxn<<1]; struct E{    int to,nxt;    long long val;}e[maxn<<2]; int f[maxn],vis[maxn],head[maxn],fa[maxn]; long long dis[maxn]; int findfa(int x){    return f[x]==x?x:f[x]=findfa(f[x]);} void addedge(int x,int y,long long z){    e[++cnt].to=y;    e[cnt].nxt=head[x];    head[x]=cnt;    e[cnt].val=z;} void uni(int x,int y,long long z){    f[findfa(x)]=findfa(y);    addedge(x,y,z);    addedge(y,x,z);} void dfs(int x){    for(int i=head[x];i;i=e[i].nxt)    {        int y=e[i].to;        if(y!=fa[x])        {            fa[y]=x;            dis[y]=dis[x]^e[i].val;            dfs(y);        }    }} int main(){    scanf("%d%d",&n,&m);    for(int i=1;i<=n;i++)        f[i]=i;    for(int i=1;i<=m;i++)        scanf("%d%d%lld",&edge[i].u,&edge[i].v,&edge[i].w);    for(int i=1;i<=m;i++)    {        int u=edge[i].u,v=edge[i].v;        int fu=findfa(u),fv=findfa(v);        if(fu!=fv)        {            vis[i]=1;            uni(u,v,edge[i].w);        }    }    dfs(1);    for(int i=1;i<=m;i++)    {        if(!vis[i])        {            int u=edge[i].u,v=edge[i].v;            ans.add(dis[u]^dis[v]^edge[i].w);        }    }    cout<<ans.result(dis[n]);}


0 0
原创粉丝点击