【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
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 }