BZOJ 2115: [Wc2011] Xor

来源:互联网 发布:mysql事务隔离级别 编辑:程序博客网 时间:2024/05/21 09:16

贪心求线性基+找环

挂题解:http://www.cnblogs.com/BLADEVIL/p/3484486.html

任何复杂环一定能由简单环异或得到

任何一条1~n的路径的异或值都可以通过其他的1~n的路径异或一些环得到

然后求出所有环,搞出线性基,贪心一下即可

简单环的个数一定是m-n+1

#include<cstdio>#include<algorithm>#define N 50005#define M 100005#define reg register#define ll long longusing namespace std;struct edge{int next,to;ll val;}e[M<<1];int ecnt = 1, last[N], cnt, dep[N];ll a[M], f[N];void addedge(int a, int b ,ll c){    e[++ecnt]=(edge){last[a],b,c};    last[a]=ecnt;}void dfs(int x, ll sum, int from){    dep[x]=dep[e[from].to]+1;    f[x]=sum;    for(int i = last[x]; i; i=e[i].next)    {        int y=e[i].to;        if(i==from)continue;        if(dep[y] && dep[y]<=dep[x])        {            a[++cnt]=f[x]^f[y]^e[i].val;        }        else if(!dep[y])        {            dfs(y,sum^e[i].val,i^1);        }    }}int main(){    int n, m;    ll ans=0;    scanf("%d%d",&n,&m);    for(int i = 1; i <= m; i++)    {        int a, b; ll c;        scanf("%d%d%lld",&a,&b,&c);        addedge(a,b,c);        addedge(b,a,c);    }    dfs(1,0,0);    ans=f[n];    int tot=0;    for(ll pos = 1ll<<59; pos; pos>>=1)    {        int i;        for(i = tot+1; i <= cnt; i++)            if(a[i]&pos)            {                ++tot;                swap(a[tot],a[i]);                break;            }        if(i<=cnt)        {            if((ans&pos)==0)ans^=a[tot];             for(int j = tot+1; j <= cnt; j++)                if(a[j]&pos)                    a[j]^=a[tot];        }           }    printf("%lld\n",ans);}
0 0
原创粉丝点击