zoukankan      html  css  js  c++  java
  • [WC2011]最大XOR和路径「线性基+图论」

    题目描述

    这不是个链接

    思路分析

    谁推荐的题怎么全是新知识啊
    如果你不会线性基,请出门左转学习这篇博客,然后切掉这道题【模板】线性基再回来看这道题。

    • 异或真是个神奇的东西!!!
    • 题目中要求路径必须是从 (1)(n) 的路径,然后显然这条路径不唯一,不仅如此,还会有环。
    • 首先从 (1) 进行 (dfs) 跑一遍简单路径,并在过程中找出所有的环。当然,不一定遍历到所有的环,但没遍历到的对答案没有影响,因为要求的是 (1)(n)
    • 考虑这些环可能依附简单路径的上,即可经过可不经过。这种情况很简单,用线性基判断一下经不经过就好了。还有一种情况就是因为一个环的出现而形成了多条简单路径(像钥匙扣一样)。这时候就可以利用异或的性质,因为我们 (dfs) 时已经求出了一条简单路径,那么我们用这个环异或一下这个路径就可以得到另一条路径,所以还是可以用线性基处理。
    • 最后在概述一下:先 (dfs) 求出到达 (n) 的简单路径的异或长度并找出途中的环,以简单路径的长度为初始答案,再用线性基拿所有的环长去更新答案就好了

    (Code)

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #define N 200010
    #define R register
    #define ll long long
    using namespace std;
    inline ll read(){
    	ll x = 0,f = 1;
    	char ch = getchar();
    	while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    	return x*f;
    }
    int n,m,head[N],tot;
    ll circle[N],dis[N],p[N];
    bool vis[N];
    struct edge{
    	int to,next;
    	ll val;
    }e[N<<2];
    int len;
    void addedge(int u,int v,ll w){
    	e[++len].to = v;
    	e[len].val = w;
    	e[len].next = head[u];
    	head[u] = len;
    }
    void dfs(int u,int fa){
    	vis[u] = 1;
    	for(R int i = head[u];i;i = e[i].next){
    		int v = e[i].to;
    		if(v==fa)continue;
    		if(vis[v]){
    			 circle[++tot] = dis[u]^dis[v]^e[i].val;//环长(指异或和)
    			 continue;
    		}
    		dis[v] = dis[u]^e[i].val;
    		dfs(v,u);
    	}
    }
    void build(){
    	for(R int i = 1;i <= tot;i++){//每个环进行一遍线性基处理
    		for(R int j = 62;j>=0;j--){
    			if(!(circle[i]>>j))continue;
    			if(!p[j]){p[j]=circle[i];break;}
    			circle[i] ^= p[j];
    		}
    	}
    }
    int main(){
    	n = read(),m = read();
    	for(R int i = 1;i <= m;i++){
    		int x = read(),y = read();
    		ll z = read();
    		addedge(x,y,z),addedge(y,x,z);
    	}
    	dfs(1,0);
    	build();
    	ll ans = dis[n];
    	for(R int i = 62;i>=0;i--){
    		if((ans^p[i])>ans)ans ^= p[i];
    	}
    	printf("%lld
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    关于Netty4.x中文教程系列更新进度的说明和道歉
    Netty4.x中文教程系列(四) ChannelHandler
    Netty4.x中文教程系列(三) Hello World !详解
    Netty4.x中文教程系列(二) Hello World !
    Netty4.x中文教程系列(一) 目录及概述
    【推荐】HTML5 UI框架 推荐
    【转载】【JQuery学习】jQuery插件开发
    前端与后端的数据交互(jquery ajax+python flask)
    【JS教程32】ajax
    【JS教程31】json
  • 原文地址:https://www.cnblogs.com/hhhhalo/p/13856201.html
Copyright © 2011-2022 走看看