2 3 3 1 2 1 1 3 2 2 3 0 6 7 1 2 1 1 3 1 2 3 1 3 4 4 4 5 2 4 6 2 5 6 2
Case #1: 3 Case #2: 3HintA XOR takes two bit patterns of equal length and performs the logical exclusive OR operation on each pair of corresponding bits. The result in each position is 1 if only the first bit is 1 or only the second bit is 1, but will be 0 if both are 0 or both are 1. In this we perform the comparison of two bits, being 1 if the two bits are different, and 0 if they are the same.
题意:求一个环路使得路径的xor和最大,环路上的边可以走多次。
BZOJ2115和这个题类似:点击打开链接
参考:http://www.cnblogs.com/andyqsmart/p/4968589.html
非常神奇优美的性质。把路径分解成若干个独立回路,然后最终的回路一定可以看成某些
独立回路的组合,然后从高位开始每一位都高斯消元寻找解。
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <vector> #include <queue> using namespace std; #define maxn 51111 #define maxm 211111 struct node { int u, v, next; long long w; } edge[maxm]; int n, m; int head[maxn], cnt; long long s[maxm], tot;//独立回路 int vis[maxn];//时间戳 long long cur[maxn];//到当前节点为止的xor和 long long ans; void add_edge (int u, int v, long long w) { edge[cnt].u = u ,edge[cnt].v = v, edge[cnt].w = w, edge[cnt].next = head[u]; head[u] = cnt++; } void dfs (int u, int fa, int pre) { vis[u] = pre; for (int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].v; if (v == fa) continue; if (vis[v] != -1) { if (vis[v] <= pre) //后继节点已经访问过 s[tot++] = cur[u]^cur[v]^edge[i].w; } else { cur[v] = cur[u]^edge[i].w; dfs (v, u, pre+1); } } } void solve () { int row = 0; for (int i = 61; i >= 0; i--) { int j; for (j = row; j < tot; j++) { if (s[j]&((long long)1 << i)) break; } if (j < tot) { swap (s[row], s[j]); for (j = 0; j < tot; j++) if (j != row) { if (s[j]&((long long)1 << i)) s[j] ^= s[row]; } row++; } } ans = 0; for (int i = 0; i < row; i++) { ans = max (ans, ans^s[i]); } printf ("%lld\n", ans); } int main () { int t, kase = 0; scanf ("%d", &t); while (t--) { printf ("Case #%d: ", ++kase); scanf ("%d%d", &n, &m); memset (head, -1, sizeof head); cnt = tot = 0; for (int i = 0; i < m; i++) { int u, v; long long w; scanf ("%d%d%lld", &u, &v, &w); add_edge (u, v, w); add_edge (v, u, w); } memset (vis, -1, sizeof vis); cur[1] = 0; dfs (1, 0, 0); solve (); } return 0; }