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

    如果没有环的话那么从1到n的路径就是唯一的,如果有环的话那么环要么不走,要么就走一圈,(走两圈异或完就和没走一样了)。

    把所有环的权值记下来,然后搞一个线性基,然后从高位到低位贪心地取即可。

    Code

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <algorithm>
      4 #include <cmath>
      5 
      6 #ifdef WIN32
      7     #define LL "%I64d"
      8 #else
      9     #define LL "%lld"
     10 #endif
     11 
     12 #ifdef CT
     13     #define debug(...) printf(__VA_ARGS__)
     14     #define setfile() 
     15 #else
     16     #define debug(...)
     17     #define filename ""
     18     #define setfile() freopen(filename".in", "r", stdin); freopen(filename".out", "w", stdout)
     19 #endif
     20 
     21 #define R register
     22 #define getc() (_S == _T && (_T = (_S = _B) + fread(_B, 1, 1 << 15, stdin), _S == _T) ? EOF : *_S++)
     23 #define dmax(_a, _b) ((_a) > (_b) ? (_a) : (_b))
     24 #define dmin(_a, _b) ((_a) < (_b) ? (_a) : (_b))
     25 #define cmax(_a, _b) (_a < (_b) ? _a = (_b) : 0)
     26 #define cmin(_a, _b) (_a > (_b) ? _a = (_b) : 0)
     27 #define cabs(_x) ((_x) < 0 ? (- (_x)) : (_x))
     28 char _B[1 << 15], *_S = _B, *_T = _B;
     29 typedef unsigned long long ull;
     30 inline int F()
     31 {
     32     R char ch; R int cnt = 0; R bool minus = 0;
     33     while (ch = getc(), (ch < '0' || ch > '9') && ch != '-') ;
     34     ch == '-' ? minus = 1 : cnt = ch - '0';
     35     while (ch = getc(), ch >= '0' && ch <= '9') cnt = cnt * 10 + ch - '0';
     36     return minus ? -cnt : cnt;
     37 }
     38 inline ull Fl()
     39 {
     40     R char ch; R ull cnt = 0; R bool minus = 0;
     41     while (ch = getc(), (ch < '0' || ch > '9') && ch != '-') ;
     42     ch == '-' ? minus = 1 : cnt = ch - '0';
     43     while (ch = getc(), ch >= '0' && ch <= '9') cnt = cnt * 10 + ch - '0';
     44     return minus ? -cnt : cnt;
     45 }
     46 #define maxn 50010
     47 #define maxm 200010
     48 struct Edge
     49 {
     50     Edge *next;
     51     int to;
     52     ull w;
     53 }*last[maxn], e[maxm], *ecnt = e;
     54 inline void link(R int a, R int b)
     55 {
     56     R ull w = Fl();
     57 //    printf("%d %d %lld
    ", a, b, w );
     58     *++ecnt = (Edge) {last[a], b, w}; last[a] = ecnt;
     59     *++ecnt = (Edge) {last[b], a, w}; last[b] = ecnt;
     60 }
     61 bool vis[maxn];
     62 ull dis[maxn], c[maxm], b[110];
     63 int cnt;
     64 void dfs(R int x)
     65 {
     66     vis[x] = 1;
     67 //    printf("dfn = %d
    ", x );
     68     for (R Edge *iter = last[x]; iter; iter = iter -> next)
     69         if (!vis[iter -> to])
     70         {
     71             dis[iter -> to] = dis[x] ^ iter -> w;
     72             dfs(iter -> to);
     73         }
     74         else c[++cnt] = dis[x] ^ dis[iter -> to] ^ iter -> w;
     75 }
     76 int main()
     77 {
     78 //    setfile();
     79     R int n = F(), m = F(), k;
     80     for (R int i = 1; i <= m; ++i)
     81         link(F(), F());
     82     dfs(1);
     83     R int len = 0;
     84 //    printf("%d
    ", cnt );
     85     for (R int i = 1; i <= cnt; ++i)
     86     {
     87         R ull x = c[i];
     88 //        printf("%llu
    ", c[i] );
     89 
     90         cmax(len, 63 - __builtin_clzll(x));
     91         for (; x; )
     92         {
     93             k = 63 - __builtin_clzll(x);
     94             if (!b[k])
     95             {
     96                 b[k] = x;
     97                 break;
     98             }
     99             x ^= b[k];
    100         }
    101     }
    102 
    103     for (R int i = 0; i <= len; ++i)
    104         if (b[i])
    105             for (R int j = i + 1; j <= len; ++j)
    106                 if (b[j] & (1ull << i))
    107                     b[j] ^= b[i];
    108 
    109     R ull ans = dis[n];
    110 
    111     for (R int i = 0; i <= len; ++i) if (b[i]) cmax(ans, ans ^ b[i]);
    112     printf("%llu
    ", ans );
    113     return 0;
    114 }
  • 相关阅读:
    五十二、使用Adb命令卸载android应用配置方法
    五十五、application用法
    五十七、SlidingDrawer (抽屉)的用法
    五十三、android启动过程
    六十、百度地图
    六十一、ListView,GridView和ScrollView上拉刷新和下拉更多
    显示设备信息
    打开HTML代码对应的页面
    体质指数计算
    OpenWebPage
  • 原文地址:https://www.cnblogs.com/cocottt/p/6685475.html
Copyright © 2011-2022 走看看