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

    2115: [Wc2011] Xor

    Time Limit: 10 Sec  Memory Limit: 259 MB

    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

    题解:

      整个1->n的过程就是 一堆环和一条简单路径的异或和

      任意环的异或和 任意组合起来,这个可以高斯消元求解,偷个懒利用线性基也是可以的

      15年ccpc南阳与这个题做法相同,,算是双倍经验题:传送门

    #include<bits/stdc++.h>
    using namespace std;
    #define ls i<<1
    #define rs ls | 1
    #define mid ((ll+rr)>>1)
    #define pii pair<int,int>
    #define MP make_pair
    typedef long long LL;
    typedef unsigned long long ULL;
    const long long INF = 1e18+1LL;
    const double pi = acos(-1.0);
    const int N=5e5+20,M=1e6+10,inf=2147483647;
    
    
    LL dep[N],a[N],ins[N],ans;
    int n,m,vis[N],cnt,t = 2,head[N],has[N];
    struct ss {
        int to,next,id;
        LL c;
    }e[N * 2];
    void add(int u,int v,LL w,int id) {
        e[t].next = head[u];
        e[t].to = v;
        e[t].c = w;
        e[t].id = id;
        head[u] = t++;
    }
    void dfs(int u,int f) {
        vis[u] = vis[f] + 1;
        for(int i = head[u]; i; i = e[i].next) {
            int to = e[i].to;
            if(has[e[i].id] || (vis[to] && vis[to] < vis[u])) continue;
            if(vis[to]) {
                a[++cnt] = dep[to] ^ dep[u] ^ e[i].c;
                continue;
            }
            has[e[i].id] = 1;
            dep[to] = dep[u] ^ e[i].c;
            dfs(to,u);
        }
    }
    void go(int u,LL now) {
        if(u == n) {
            LL ret = now;
             for(int i = 62; i >= 0; --i)
                  if((ins[i]^ret) > ret) ret^=ins[i];
            ans = max(ans,ret);
            return ;
        }
        vis[u] = 1;
        for(int i = head[u]; i; i = e[i].next) {
            int to = e[i].to;
            if(has[e[i].id]) continue;
            has[e[i].id] = 1;
            go(to,now^e[i].c);
        }
        vis[u] = 0;
    }
    int main() {
        scanf("%d%d",&n,&m);
        for(int i = 1; i <= m; ++i) {
            int x,y;LL z;
            scanf("%d%d%lld",&x,&y,&z);
            if(x == y) {
                a[++cnt] = z;
                continue;
            }
            add(x,y,z,i),add(y,x,z,i);
        }
        dfs(1,0);
        for(int i = 1; i <= cnt; ++i) {
            for(int j = 62; j >= 0; --j) {
                if(a[i]&(1LL<<j)) {
                    if(!ins[j]) {
                        ins[j] = a[i];
                        break;
                    }
                    a[i] ^= ins[j];
                }
            }
        }
        ans = 0;
        memset(vis,0,sizeof(vis));
        memset(has,0,sizeof(has));
        go(1,0);
        cout<<ans<<endl;
        return 0;
    }
  • 相关阅读:
    感知机学习算法 python实现
    最小二乘法 python实现
    python数据结构与算法——图的基本实现及迭代器
    python数据结构与算法——二叉树结构与遍历方法
    python数据结构与算法——字典树
    python数据结构与算法——完全树 与 最小/大堆
    win2008服务器asp站点配置要点
    SQL Server分页语句ROW_NUMBER,读取第4页数据,每页10条
    WinForm Control.Invoke&Control.BeginInvoke异步操作控件实例
    Couchbase应用示例(初探)
  • 原文地址:https://www.cnblogs.com/zxhl/p/7406754.html
Copyright © 2011-2022 走看看