• BZOJ 2115:Xor(线性基+DFS)


    题目链接

    题意

    中文题意

    思路

    因为存在环和重边,边来回走是没有意义的,因此最终的答案应该是一条从1到n的路径权值异或上若干个环的权值,那么难点在于如何选取这些环的权值使得最终的答案更优。

    使用到线性基的贪心算法来计算。DFS处理出环的异或值,然后将这些值加入到线性基中,贪心选取。

    参考

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef pair<int, int> pii;
    const int INF = 0x3f3f3f3f;
    const int N = 5e4 + 11;
    struct Edge {
    	int v, nxt;
    	LL w;
    } edge[N*4];
    int n, m, head[N], vis[N], cnt, tot;
    LL p[70], ans, cir[N*4], dis[N];
    
    void Add(int u, int v, LL w) {
    	edge[tot] = (Edge) { v, head[u], w }; head[u] = tot++;
    	edge[tot] = (Edge) { u, head[v], w }; head[v] = tot++;
    }
    
    void dfs(int u) {
    	for(int i = head[u]; ~i; i = edge[i].nxt) {
    		int v = edge[i].v; LL w = edge[i].w;
    		if(vis[v]) cir[++cnt] = dis[v] ^ dis[u] ^ w;
    		else vis[v] = 1, dis[v] = dis[u] ^ w, dfs(v);
    	}
    }
    
    int main() {
    	scanf("%d%d", &n, &m);
    	memset(head, -1, sizeof(head));
    	ans = cnt = tot = 0;
    	for(int i = 1; i <= m; i++) {
    		int u, v; LL w;
    		scanf("%d%d%lld", &u, &v, &w);
    		Add(u, v, w);
    	}
    	memset(p, 0, sizeof(p));
    	memset(vis, 0, sizeof(vis));
    	vis[1] = 1; dfs(1);
        for(int i = 1; i <= cnt; i++) {
            for(int j = 63; j >= 0; j--) {
                if(((cir[i] >> j) & 1) == 0) continue;
                if(!p[j]) { p[j] = cir[i]; break; }
                cir[i] ^= p[j];
            }
        } ans = dis[n];
        for(int i = 63; i >= 0; i--)
            if((ans ^ p[i]) > ans) ans ^= p[i];
    	printf("%lld
    ", ans);
    	return 0;
    }
    
  • 相关阅读:
    Python三维绘图--Matplotlib colorbar生成
    Python三维绘图--Matplotlib
    VIM剪切板的使用
    三维点云网络PointNet——模型及代码分析
    ECCV2018--点云匹配
    hdu 1905 小数化分数2
    hdu 1755 A Number Puzzle
    hdu 1796 How many integers can you find
    hdu 1452 Happy 2004
    hdu 2837 Calculation
  • 原文地址:https://www.cnblogs.com/fightfordream/p/7647114.html
Copyright © 2020-2023  润新知