zoukankan      html  css  js  c++  java
  • 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

    Solution

    首先这个答案肯定是由一条简单路径和几个环构成的。简单路径外的环,我们是可以想用就用的,因为我们可以走到环那里绕一圈再回到起点,这样除了那个环之外别的地方都没有受到影响。

    怎么求出所有的环呢?其实就是$DFS$树所有的反祖边和树边构成的环,$DFS$一下就可以找出来了。

    我们找出所有的环,再随便找一条$1$到$n$的简单路径,用简单路径的$xor$去在环的线性基里找最大就好了。

    为什么随便找一条简单路径是对的呢?因为我们找出的所有环中,肯定有在简单路径上的,这样的话简单路径在异或上这些环后,就会变成一条新的简单路径,这样调整下来最后肯定能得到最优解。

    Code

     1 #include<iostream>
     2 #include<cstdio>
     3 #define N (200009)
     4 #define LL long long
     5 using namespace std;
     6 
     7 struct Edge{LL to,next,len;}edge[N<<1];
     8 LL n,m,u,v,l,cnt;
     9 LL head[N],num_edge;
    10 LL d[N],Xor[N],Circle[N];
    11 bool vis[N];
    12 
    13 void add(LL u,LL v,LL l)
    14 {
    15     edge[++num_edge].to=v;
    16     edge[num_edge].len=l;
    17     edge[num_edge].next=head[u];
    18     head[u]=num_edge;
    19 }
    20 
    21 void Insert(LL x)
    22 {
    23     for (int i=62; i>=0; --i)
    24         if (x&(1ll<<i))
    25         {
    26             if (!d[i]) {d[i]=x; break;}
    27             x^=d[i];
    28         }
    29 }
    30 
    31 void DFS(LL x)
    32 {
    33     vis[x]=1;
    34     for (int i=head[x]; i; i=edge[i].next)
    35     {
    36         int y=edge[i].to;
    37         if (!vis[y]) Xor[y]=Xor[x]^edge[i].len, DFS(y);
    38         else Circle[++cnt]=Xor[y]^Xor[x]^edge[i].len;
    39     }
    40 }
    41 
    42 int main()
    43 {
    44     scanf("%lld%lld",&n,&m);
    45     for (int i=1; i<=m; ++i)
    46     {
    47         scanf("%lld%lld%lld",&u,&v,&l);
    48         add(u,v,l); add(v,u,l);
    49     }
    50     DFS(1);
    51     for (int i=1; i<=cnt; ++i)
    52         Insert(Circle[i]);
    53     LL ans=Xor[n];
    54     for (int i=62; i>=0; --i)
    55         ans=max(ans,ans^d[i]);
    56     printf("%lld
    ",ans);
    57 }
  • 相关阅读:
    如何将网格式报表打印成其它样式
    拥有与实力不相称的脾气是种灾难——北漂18年(23)
    8.8.1 Optimizing Queries with EXPLAIN
    mysql 没有rowid 怎么实现根据rowid回表呢?
    secondary index
    8.5.5 Bulk Data Loading for InnoDB Tables 批量数据加载
    mysql 中key 指的是索引
    8.5.4 Optimizing InnoDB Redo Logging 优化InnoDB Redo 日志
    8.5.3 Optimizing InnoDB Read-Only Transactions 优化InnoDB 只读事务
    8.5.1 Optimizing Storage Layout for InnoDB Tables InnoDB表的存储布局优化
  • 原文地址:https://www.cnblogs.com/refun/p/10277334.html
Copyright © 2011-2022 走看看