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 }
  • 相关阅读:
    [转]翻译:使用.net3.5的缓存池和SocketAsyncEventArgs类创建socket服务器
    强制将IE,Chrome设置为指定兼容模式来解析(转)
    MySQL vs NoSQL 效率与成本之争(转)
    Configure the max limit for concurrent TCP connections
    在as3中Embed(绑定)flash动画元素
    使用ASP.NET Global.asax 文件(转)
    AspExe a small ASP.NET compiler and executor for document generation
    [转]vim + cscope/ctags 查看分析代码
    编译Chromium 遇到的问题
    yum与apt命令比较
  • 原文地址:https://www.cnblogs.com/refun/p/10277334.html
Copyright © 2011-2022 走看看