• BZOJ2115: [Wc2011] Xor(Dfs树,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

    解题思路:

    神题!!!

    就是说发现如果存在简单路径最大,那么一定会采取,而且不会蹭来蹭去的因为会被异或掉是徒劳的。

    现在考虑一个问题:这条路径可不可以被拓展呢。

    好像是可以的,而且只能这样拓展:走到一个环,然后原路返回。

    这样就只需要Dfs树一遍,将非树边更新至线性无关组里,

    最后查最大异或和就好了。

    代码:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 typedef long long lnt;
     5 struct pnt{
     6     int hd;
     7     lnt dis;
     8     bool vis;
     9 }p[100000];
    10 struct ent{
    11     int twd;
    12     int lst;
    13     lnt vls;
    14 }e[1000000];
    15 int cnt;
    16 int n,m;
    17 lnt b[70];
    18 void ade(int f,int t,lnt v)
    19 {
    20     cnt++;
    21     e[cnt].twd=t;
    22     e[cnt].vls=v;
    23     e[cnt].lst=p[f].hd;
    24     p[f].hd=cnt;
    25     return ;
    26 }
    27 bool Insert(lnt x)
    28 {
    29     for(int i=62;i>=0;i--)
    30     {
    31         if(x&(1ll<<i))
    32         {
    33             if(b[i]==-1)
    34             {
    35                 b[i]=x;
    36                 return true;
    37             }else x^=b[i];
    38         }
    39     }
    40     return false;
    41 }
    42 lnt Query(lnt x_)
    43 {
    44     for(int i=62;i>=0;i--)
    45         x_=std::max(x_,x_^b[i]);
    46     return x_;
    47 }
    48 void Dfs(int x_)
    49 {
    50     p[x_].vis=true;
    51     for(int i=p[x_].hd;i;i=e[i].lst)
    52     {
    53         int t_=e[i].twd;
    54         if(p[t_].vis)Insert(p[t_].dis^p[x_].dis^e[i].vls);
    55         else{
    56             p[t_].dis=p[x_].dis^e[i].vls;
    57             Dfs(t_);
    58         }
    59     }
    60     return ;
    61 }
    62 int main()
    63 {
    64     memset(b,-1,sizeof(b));
    65     scanf("%d%d",&n,&m);
    66     for(int i=1;i<=m;i++)
    67     {
    68         int x,y;
    69         lnt c;
    70         scanf("%d%d%lld",&x,&y,&c);
    71         ade(x,y,c),ade(y,x,c);
    72     }
    73     Dfs(1);
    74     printf("%lld
    ",Query(p[n].dis));
    75     return 0;
    76 }
  • 相关阅读:
    2.11 Go接口内部实现
    2.08 Go之类型分支(switch判断空接口中变量的类型)
    2.08 Go之使用空接口实现保存任意值的字典
    2.07 Go之接口和类型之间的转换
    1.28 Go之接口的嵌套组合
    2.11 Go之error接口
    libpng.md
    5_中间件.md
    8_多服务运行.md
    6_模板与渲染.md
  • 原文地址:https://www.cnblogs.com/blog-Dr-J/p/10285402.html
Copyright © 2020-2023  润新知