zoukankan      html  css  js  c++  java
  • P4551 最长异或路径 题解

    P4551 最长异或路径

    前置知识:01trie

    是trie的一种。每个节点是0或者1,我们可以将一些数以二进制表示的形式存入01trie,进而解决一些异或问题。有关trie树的原理再次不在赘述。可上百度自行搜索或阅读有关(oi)书籍。


    异或,指一个法则:

    两个数的二进制数位上相等即为0,不相等即为1。

    显然,一个数对同一个数异或两次等于没有异或,

    那么异或也就满足交换律,结合律。

    对于一列数的异或和,我们可以将其用结合律从1~i,i+1~j进行异或,然后在将这两个结果进行异或,结果不变。

    于是我们可以:

    1. 处理出1到每一个节点的异或和

    2. 把他们加到一棵(01trie)里面

    3. 从高位到低位贪心操作,取最大值,即是答案。

    代码:

    #include<cstdio>
    #include<iostream>
    #define N 100007
    using namespace std;
    inline int read()
    {
    	int x=0,f=1; char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    	return x*f;
    }
    struct edg{
    	int next,to,dis;
    }edge[N*2];
    int t[N<<5][2];
    int n,m,u,v,w,num,hea[N],d[N],tot;
    inline void add(int from,int to,int dis)
    {
    	num++;
    	edge[num].dis=dis;
    	edge[num].to=to;
    	edge[num].next=hea[from];
    	hea[from]=num;
    }
    void dfs(int now,int fa)
    {
    	for(int i=hea[now];i;i=edge[i].next)
    	{
    		int v=edge[i].to;
    		if(v!=fa)
    		{
    			d[v]=d[now]^edge[i].dis;
    			dfs(v,now);
    		}
    	}
    }
    void build_trie(int n,int now)
    {
    	for(int i=30;i>=0;i--)
    	{
    		int c=(n>>i)&1;
    		if(!t[now][c])t[now][c]=++tot;
    		now=t[now][c];
    	}
    }
    int query(int n,int now)
    {
    	int ans=0;
    	for(int i=30;i>=0;i--)
    	{
    		int c=(n>>i)&1;
    		if(t[now][c^1])
    		{
    			ans+=(1<<i),now=t[now][c^1];
    		}
    		else now=t[now][c];
    	}
    	return ans;
    }
    int main(){
    	n=read();
    	int ans=0;
    	for(int i=1;i<n;i++)
    	{
    		u=read(),v=read(),w=read();
    		add(u,v,w);add(v,u,w);
    	}
    	dfs(1,0);
    	for(int i=1;i<=n;i++)build_trie(d[i],0);
    	for(int i=1;i<=n;i++)
    	{
    		ans=max(ans,query(d[i],0));
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    
    

    完结。

  • 相关阅读:
    centos ssh远程登陆
    Vim 技巧
    php and js to facebook登陆 最佳实践
    vim 编辑器常规操作
    js 函数定义三种方式
    ORDER BY 默认升序排列
    sql = 和<>遵循的sql-92标准的设置SET ANSI_NULLS ON
    添加FB登陆时,需要curl扩展
    array(1) { [0]=> int(5) }和array(1) { [0]=> string(1) "5" }
    Android第三方推送引擎比较
  • 原文地址:https://www.cnblogs.com/lbssxz/p/13267156.html
Copyright © 2011-2022 走看看