• bzoj2115: [Wc2011] Xor


    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

     

    首先一条路径的异或和可以化为一条1到n的简单路径和一些简单环的异或和

    我们首先DFS求出任意一条1到n的简单路径以及图中所有最简单的简单环(环上不存在两个点可以通过环外边直连)

    然后在一些数中选出一个子集,使它们与一个给定的数的异或和最大,这就是高斯消元的问题了

    利用高斯消元使每一位只存在于最多一个数上 然后贪心求解即可

    code:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<algorithm>
     6 #define maxn 50005
     7 #define maxm 200005
     8 using namespace std;
     9 typedef long long int64;
    10 char ch;
    11 int n,m,a,b,tot,now[maxn],son[maxm],pre[maxm],N;
    12 int64 val[maxm],f[maxn],A[maxm],c,ans;
    13 bool ok,bo[maxn];
    14 void read(int &x){
    15     for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=1;
    16     for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
    17     if (ok) x=-x;
    18 }
    19 void read(int64 &x){
    20     for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=1;
    21     for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
    22     if (ok) x=-x;
    23 }
    24 void dfs(int u){
    25     bo[u]=1;
    26     for (int p=now[u],v=son[p];p;p=pre[p],v=son[p])
    27         if (!bo[v]) f[v]=f[u]^val[p],dfs(v);
    28         else A[++N]=f[u]^f[v]^val[p];
    29 }
    30 void put(int a,int b,int64 c){pre[++tot]=now[a],now[a]=tot,son[tot]=b,val[tot]=c;}
    31 void gauss(){
    32     int i,j,k;
    33     for (i=60,k=1;i>=0;i--){
    34         for (j=k;j<=N&&!(A[j]&(1LL<<i));j++);
    35         if (j<=N){
    36             swap(A[k],A[j]);
    37             for (j=1;j<=N;j++) if (j!=k&&(A[j]&(1LL<<i))) A[j]^=A[k];
    38             k++;
    39         }
    40     }
    41     N=k-1;
    42 }
    43 int main(){
    44     read(n),read(m);
    45     for (int i=1;i<=m;i++) read(a),read(b),read(c),put(a,b,c),put(b,a,c);
    46     dfs(1),gauss(),ans=f[n];
    47     for (int i=1;i<=N;i++) ans=max(ans,ans^A[i]);
    48     printf("%lld
    ",ans);
    49     return 0;
    50 }
  • 相关阅读:
    goj 来自不给标题的菜鸟出题组(巴什博弈+素数判定)
    goj 城市交通线(简单并查集)
    ACM_鸡兔同笼(二元一次方程)
    ACM_魔仙岛探险(深搜)
    ACM_螺旋填数
    ACM_开心消消乐
    构建工具是如何用 node 操作 html/js/css/md 文件的
    学习使用ExpressJS 4.0中的新Router
    请求时token过期自动刷新token
    Express的基本使用
  • 原文地址:https://www.cnblogs.com/chenyushuo/p/4682178.html
Copyright © 2020-2023  润新知