zoukankan      html  css  js  c++  java
  • Bzoj2110--Wc2011Xor

    考虑如果我们已经到达了终点,那么从终点出发显然可以异或上图中任何地方一个环的异或值后再回到终点,那么我们显然可以在到达终点后根据环的异或值调整自己

    所以我们可以先处理出环上的异或值,我的做法是先做一颗生成树,然后dfs确定每个点到根的异或值再加入非树边,这时每条非树边都对应一个环,其他复杂环都可以由这些环互相异或得到。处理下线性基在贪心选取。

    有个小细节是树边上1到n的路径是必须选的,所以要基于这条路径贪心。

    代码:

    #include<bits/stdc++.h>
    #define INF 1000000000
    #define LNF 100000000000000ll
    #define eps 1e-12
    #define LL long long
    inline int _max(int a,int b) {return a>b?a:b;}
    inline long double _fabs(long double a) {return a>0?a:-a;}
    
    using namespace std;
    #define MAXN 50005
    #define MAXM 100005
    
    int n,m,x[MAXN],fr[MAXM],to[MAXM],tot;
    LL gs[MAXN],cs[MAXM],ans;bool f[MAXM];
    
    int fa(int v) {
        int k=v,b=v;
        while(x[v]!=v) v=x[v];
        while(x[k]!=v) {
            x[k]=v;k=x[b];b=k;
        }
        return v;
    }
    
    int head[MAXN],cnt;
    struct Edge{
        int to,next;LL w;
    }e[MAXM];
    void insert(int a,int b,LL c) {
        e[++cnt].next=head[a];head[a]=cnt;e[cnt].to=b;e[cnt].w=c;
        e[++cnt].next=head[b];head[b]=cnt;e[cnt].to=a;e[cnt].w=c;
    }
    
    LL xr[MAXN];bool vis[MAXN];
    void dfs(int v,LL k) {
        xr[v]=k;vis[v]=1;
        for(int i=head[v];i;i=e[i].next) 
            if(!vis[e[i].to]) 
                dfs(e[i].to,k^e[i].w);
    }
    
    LL num[72];
    void Gauss() {
        for(int i=1;i<=tot;i++) 
            for(int j=62;j>=0;j--) if(gs[i]>>j&1) {
                if(num[j]) gs[i]^=num[j];else {num[j]=gs[i];break;}
            }
    }
    
    int main() {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++) x[i]=i;
        for(int a,b,i=1;i<=m;i++) {
            scanf("%d%d%lld",&fr[i],&to[i],&cs[i]);
            a=fa(fr[i]);b=fa(to[i]);
            if(a!=b) x[a]=b,insert(fr[i],to[i],cs[i]),f[i]=1;
        }
        dfs(n,0);
        for(int i=1;i<=m;i++) if(!f[i]) gs[++tot]=xr[fr[i]]^xr[to[i]]^cs[i];
        Gauss();
        ans=xr[1];
        for(int i=62;i>=0;i--) 
            if((ans^num[i])>ans) ans=ans^num[i];
        cout<<ans<<endl;
        return 0;
    }
  • 相关阅读:
    Linux安全应用之防垃圾邮件服务器的构建
    Postfix邮件系统安装配置视频
    Linux常用的安全工具
    Linux系统安全加固(一)
    全球开源软件发展趋势分析
    安装配置FreeBSD9全过程体验
    P1441-砝码称重
    POJ-2376 Cleaning Shifts
    P1514-引水入城
    P1378-油滴扩展
  • 原文地址:https://www.cnblogs.com/ihopenot/p/5952910.html
Copyright © 2011-2022 走看看