bzoj2115 Xor(线性基)
解题思路
本题的重点就是把环从路径中拿出来单独考虑,如果给你一条1到n的路径,让你往路径上加环,使得结果最大的话,相当于求几个数的子序列的最大异或和,很明显可以用线性基来做。
我们在dfs过程中存一下1号点到当前点的异或值dis[i],如果遇见了一个环,那么根据异或的性质(a xor b xor a = b),将这条边连接的两个点的dis和边权异或一下就能得到这个环的权值,然后把它加入线性基里就行了。
代码
const int maxn = 1e5+10;
const int maxm = 1e6+10;
ll dis[maxn];
bool vis[maxn];
vector<P> e[maxn];
vector<ll> s;
void insert(ll t) {
for (auto v : s) t = min(t, t^v);
for (auto &v: s) v = min(v, v^t);
if (t) s.push_back(t);
}
void dfs(int u, int p) {
vis[u] = 1;
for (auto v : e[u]) {
if (v.y==p) continue;
if (!vis[v.y]) {
dis[v.y] = dis[u]^v.x;
dfs(v.y, u);
}
else insert(dis[v.y]^v.x^dis[u]);
}
}
int main() {
IOS;
int n, m; cin >> n >> m;
for (int i = 1, a, b; i<=m; ++i) {
ll c; cin >> a >> b >> c;
e[a].push_back({c, b});
e[b].push_back({c, a});
}
dfs(1, 0);
ll ans = dis[n];
for (auto t : s) ans = max(ans, ans^t);
cout << ans << endl;
return 0;
}