zoukankan      html  css  js  c++  java
  • BZOJ 2115 [Wc2011] Xor ——线性基

    【题目分析】

        显然,一个路径走过两边是不需要计算的,所以我么找到一条1-n的路径,然后向该异或值不断异或简单环即可。

        但是找出所有简单环是相当复杂的,我们只需要dfs一遍,找出所有的环路即可,因为所有的简单环都可以经过各种各样的异或得到。

        然后线性基,在从高位向低位贪心即可,至于证明,需要拟阵的相关知识。

    【代码】

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <cmath>
     
    #include <set>
    #include <map>
    #include <string>
    #include <algorithm>
    #include <vector>
    #include <iostream>
    #include <queue>
    using namespace std;
     
    #define maxn 100005
    #define ll long long
     
    int read()
    {
        int x=0,f=1; char ch=getchar();
        while (ch<'0'||ch>'9') {if (ch=='-') f=-1; ch=getchar();}
        while (ch>='0'&&ch<='9') {x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
     
    int h[maxn],to[maxn<<1],ne[maxn<<1];
    ll w[maxn<<1];
    int en=0,n,m,vis[maxn],tot=0;
    ll a[maxn<<1];
    ll dis[maxn];
     
    void add(int a,int b,ll c)
    {
        to[en]=b;
        w[en]=c;
        ne[en]=h[a];
        h[a]=en++;
    }
     
    void dfs(int k)
    {
    //  printf("dfs on %d
    ",k);
        vis[k]=1;
        for (int i=h[k];i>=0;i=ne[i])
        {
            if (!vis[to[i]])
            {
                dis[to[i]]=dis[k]^w[i];
                dfs(to[i]);
            }
            else a[++tot]=dis[k]^dis[to[i]]^w[i];
        }
    }
     
    ll lb[64],ans;
     
    int main()
    {
        memset(h,-1,sizeof h);
        scanf("%d%d",&n,&m);
        for (int i=1;i<=m;++i)
        {
            int a,b; ll c;
            scanf("%d%d%lld",&a,&b,&c);
            add(a,b,c);
            add(b,a,c);
        }
        dfs(1);
        ans=dis[n];
    //  for (int i=1;i<=n;++i) cout<<dis[i]<<" "; cout<<endl;
    //  for (int i=1;i<=tot;++i) cout<<a[i]<<" ";cout<<endl;
        for (int i=1;i<=tot;++i)
        {
            for (int j=63;j>=0;j--)
            {
                if ((a[i]>>j)&1){
                    if (!lb[j]) {lb[j]=a[i];break;}
                    else a[i]^=lb[j];
                }
            }
        }
        for (int i=63;i>=0;i--)
            if (lb[i]&&((ans>>i)&1)==0) ans^=lb[i];
        cout<<ans<<endl;
        return 0;
    }
    

      

  • 相关阅读:
    缓存Cache
    RDD的行动操作
    redis数据库的配置
    requests的封装(user-agent,proxies)
    phantjs
    python多线程
    etree-xpath
    Flask
    Flask
    Flask
  • 原文地址:https://www.cnblogs.com/SfailSth/p/6204776.html
Copyright © 2011-2022 走看看