Problem
【WC2011】Xor
TimeLimit:10Sec
MemoryLimit:259MB
Description
![](https://www.lydsy.com/JudgeOnline/images/2606_1.jpg)
第一行包含两个整数N和M,表示该无向图中点的数目与边的数目。
接下来M行描述M条边,每行三个整数Si,Ti,Di,表示Si与Ti之间存在 一条权值为Di的无向边。
图中可能有重边或自环。
Output
仅包含一个整数,表示最大的Xor和(十进制结果),注意输出后加换行回车。
1 2 3 4 5 6 7 8
| 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
Hint
![](https://www.lydsy.com/JudgeOnline/images/2606_3.jpg)
标签:线性基
Solution
线性基经典题。
对于一条非简单的路径,其异或和等于其中的简单路径异或和异或上经过的环的异或和,即选取一条简单路径和若干环,此简单路径到环的那段路径会经过两次,因而异或和消成0。
因此只用选出一条从1到n的简单路径异或和,再异或上若干环的异或和使总和最大即可。
于是暴力DFS找到简单路径异或和和所有环的异或和,对所有环的异或和求线性基,贪心选最大和即可。
Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| #include <bits/stdc++.h> #define SZ 60 #define MAX_N 50000 using namespace std; typedef long long lnt; template <class T> inline void read(T &x) { x = 0; int c = getchar(), f = 1; for (; !isdigit(c); c = getchar()) if (c == 45) f = -1; for (; isdigit(c); c = getchar()) (x *= 10) += f*(c-'0'); } int n, m; lnt b[SZ+5], dis[MAX_N+5]; bool mrk[MAX_N+5]; vector <int> G[MAX_N+5]; vector <lnt> E[MAX_N+5]; void insert(lnt x) { for (int i = SZ; ~i; i--) if (x>>i&1) { if (b[i]) x ^= b[i]; else {b[i] = x; break;} } } void DFS(int u) { for (int i = 0, v; i < (int)G[u].size(); i++) if (mrk[v = G[u][i]]) insert(dis[u]^dis[v]^E[u][i]); else dis[v] = dis[u]^E[u][i], mrk[v] = true, DFS(v); } int main() { read(n), read(m); for (int i = 0, u, v; i < m; i++) { lnt c; read(u), read(v), read(c); G[u].push_back(v), E[u].push_back(c); G[v].push_back(u), E[v].push_back(c); } DFS(1); lnt mx = dis[n]; for (int i = SZ; ~i; i--) if (!(mx>>i&1)) mx ^= b[i]; return printf("%lld\n", mx), 0; }
|