线性基+图

线性基+图

2115: [Wc2011] Xor

求1到n的最大异或;

把环都记录下来,然后弄到线性基,答案的初始值是1到n的任意一条路径。

#include <cstdio>
#include <cstring>
typedef long long LL;
LL p[70], circle[1000010], d[1000010];
int cnt = 0, ct = 0, head[1000010], vis[1000010];
struct edge
{
    int next, to;
    LL w;
}G[1000010];

void add(int u, int v, LL w) {
    G[cnt].w = w;
    G[cnt].to = v;
    G[cnt].next = head[u];
    head[u] = cnt++;
}
void dfs(int x) {
    vis[x] = 1;
    for(int i = head[x]; i != -1; i = G[i].next) {
        int v = G[i].to;
        if(vis[v]) circle[ct++] = d[v]^d[x]^G[i].w;
        else {
            d[v] = d[x]^G[i].w;
            dfs(v);
        }
    }
}
int main() {
    memset(head, -1, sizeof(head));
    int n, m;
    scanf("%d %d", &n, &m);
    while(m--) {
        int u, v;
        LL w;
        scanf("%d %d %lld", &u, &v, &w);
        add(u, v, w);
        add(v, u, w);
    }
    dfs(1);
    LL ans = d[n];
    for(int i = 0; i < ct; i++) {
        for(int j = 60; j >= 0; j--) {
            if(circle[i] & (1LL << j)) {
                if(p[j] == 0) {
                    p[j] = circle[i];
                    break;
                }
                circle[i] ^= p[j];
            }
        }
    }
    for(int i = 60; i >= 0; i--) {
        if((ans ^ p[i]) > ans) ans ^= p[i];
    }
    printf("%lld\n", ans);
    return 0;
}

posted @ 2020-03-31 22:08  小饭hhh  阅读(126)  评论(0编辑  收藏  举报