【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\n", 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\n", 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\n", cnt );
 85     for (R int i = 1; i <= cnt; ++i)
 86     {
 87         R ull x = c[i];
 88 //        printf("%llu\n", 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\n", ans );
113     return 0;
114 }

 

posted @ 2017-04-09 17:04  cot  阅读(146)  评论(0编辑  收藏  举报