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;
}
posted @ 2021-10-08 04:42  shuitiangong  阅读(22)  评论(0编辑  收藏  举报