zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    canvas制作简单动画
    jQuery 2.2 和 1.12 新版本发布
    jquery实现简单鼠标经过图片预览效果
    js深入理解"闭包"
    js判断一个变量是否为数组的解决方案
    js+css:43种常见的浏览器兼容性问题大汇总
    js判断当前操作系统
    js判断是否微信浏览器打开
    h5connect.js 腾讯云视频点播使用指南
    Docker入门书籍
  • 原文地址:https://www.cnblogs.com/fightfordream/p/7647114.html
Copyright © 2011-2022 走看看