zoukankan      html  css  js  c++  java
  • [洛谷P4151][WC2011]最大XOR和路径

    题目大意:给你一张$n$个点$m$条边的无向图,求一条$1->n$的路径,使得经过路径值的异或值最大(重复经过重复计算)

    题解:某条路$k$被重复走了两次,那么它的权值对答案的贡献就是$0$,但是通过这条路径$k$,可以到达它连接的另一个点。

    可以将路径拆成两部分,一部分是环,另一部分是链。假设我们选择了一条从$1->n$的链,然后可以选择一些环来增广这条链。可以枚举所有环,将环上异或和扔进线性基,然后用任意一条$1->n$的链作为初值,求线性基与这条链的最大异或和。

    卡点:

    C++ Code:

    #include <cstdio>
    #define maxn 50010
    #define maxm 100010
    int head[maxn], cnt;
    struct Edge {
    	int to, nxt;
    	long long w;
    } e[maxm << 1];
    void addE(int a, int b, long long c) {
    	e[++cnt] = (Edge) {b, head[a], c}; head[a] = cnt;
    }
    
    long long p[64];
    inline void add(long long x) {
    	for (int i = 62; ~i; i--) if (x & 1ll << i) {
    		if (p[i]) x ^= p[i];
    		else {p[i] = x; break;}
    	}
    }
    inline long long ask(long long x) {
    	long long ans = x;
    	for (int i = 62; ~i; i--) if (ans < (ans ^ p[i])) ans = ans ^ p[i];
    	return ans;
    }
    
    long long d[maxn];
    bool vis[maxn];
    void dfs(int rt, long long now) {
    	d[rt] = now;
    	vis[rt] = true;
    	for (int i = head[rt]; i; i = e[i].nxt) {
    		int v = e[i].to;
    		if (!vis[v]) dfs(v, d[rt] ^ e[i].w);
    		else add(d[rt] ^ d[v] ^ e[i].w);
    	}
    }
    int n, m;
    int main() {
    	scanf("%d%d", &n, &m);
    	for (int i = 0; i < m; i++) {
    		int a, b;
    		long long c;
    		scanf("%d%d%lld", &a, &b, &c);
    		addE(a, b, c);
    		addE(b, a, c);
    	}
    	dfs(1, 0);
    	printf("%lld
    ", ask(d[n]));
    	return 0;
    }
    

      

  • 相关阅读:
    启动时创建线程并传递数据
    C# 匿名方法 委托 Action委托 Delegate委托
    linq里的select和selectmany操作 投影运算
    C# 基础小知识之yield 关键字 语法糖
    在您的应用上运行性能测试
    loadrunner11有效的license
    30-hadoop-hbase-安装squirrel工具
    31-hadoop-hbase-mapreduce操作hbase
    29-hadoop-使用phtonenix工具&分页&数据导入
    28-hadoop-hbase入门小程序
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/9686482.html
Copyright © 2011-2022 走看看