zoukankan      html  css  js  c++  java
  • 01Trie【p4551(poj3764)】 最长异或路径

    题目描述

    给定一棵 n 个点的带权树,结点下标从 1 开始到 N 。寻找树中找两个结点,求最长的异或路径。

    异或路径指的是指两个结点之间唯一路径上的所有边权的异或。

    个人

    首先强推一下01字典树(Trie),这个东西是解决xor问题的利器.

    查找最大异或值的时候我们一般从最高位到低位向下找

       eg:   1000(2)=8(10)
             0111(2)=7(10)
    

    显然只要我的最高位是1,除非你和我的最高位相同,要不然我就是比你大.

    根据数学上的等比数列求和可知
    8=2^3 ,7=2^3-1

    所以说我们可以贪心的去找当前位^1的节点

    01字典树的写法和trie树差不多,对于这个题,

    过程:
         1.建图跑一下再去dfs去求每个节点到根节点的xor值。
         2.再去构建01Trie去实现我们的贪心即可
    

    网上讲这个的很多,想学的可以百度

    ———————代码—————————

    #include<bits/stdc++.h>
    #define IL inline
    #define RI register int
    #define maxn 100008
    int trie[maxn*31][2],xo[maxn],ans,rt;
    int val[maxn],n,head[maxn],tot;
    struct code{int u,v,w;}edge[maxn<<1];
    IL void read(int &x){
    	int f=1;x=0;char s=getchar();
    	while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();}
    	while(s<='9'&&s>='0'){x=x*10+s-'0';s=getchar();}
    	x*=f;
    }
    IL void add(int x,int y,int z)
    {
    	edge[++tot].u=head[x];
    	edge[tot].v=y;
    	edge[tot].w=z;
    	head[x]=tot;
    	edge[++tot].u=head[y];
    	edge[tot].v=x;
    	edge[tot].w=z;
    	head[y]=tot;
    }
    IL void build_trie(int x,int rt)
    {
    	for(RI i=1<<30;i;i>>=1)
    	{
    		bool c=x&i;
    		if(!trie[rt][c])trie[rt][c]=++tot;
    		rt=trie[rt][c];
    	}
    }
    IL int query(int x,int rt)
    {
    	int ans=0;
    	for(RI i=1<<30;i;i>>=1)
    	{
    		bool c=x&i;
    		if(trie[rt][c^1])ans+=i,rt=trie[rt][c^1];
    		else rt=trie[rt][c];
    	}
    	return ans;
    }
    IL void dfs(int u,int fa)
    {
    	for(RI i=head[u];i;i=edge[i].u)
    	{
    		if(edge[i].v!=fa)
    		{
    			xo[edge[i].v]=xo[u]^edge[i].w;
    			dfs(edge[i].v,u);
    		}
    	}
    }
    int main()
    {
    	read(n);
    	for(RI i=1,u,v,w;i<n;i++)read(u),read(v),read(w),add(u,v,w);
    	dfs(1,0);
    	for(RI i=1;i<=n;i++)build_trie(xo[i],rt);
    	for(RI i=1;i<=n;i++)ans=std::max(ans,query(xo[i],rt));
    	printf("%d",ans);
    }
    
  • 相关阅读:
    oracle EXP导出一张表时使用query参数指定where条件
    Centos7-安装Apache2.4+PHP5.6
    VMWare 14 Workstation Pro 下载与安装
    Mysql的视图、存储过程、函数、索引全解析
    Eclipse Java注释模板设置详解
    Tomcat 80端口 配置及域名访问步骤
    LeetCode——merge-k-sorted-lists
    LeetCode——rotate-list
    LeetCode——jump-game-ii
    LeetCode——jump-game
  • 原文地址:https://www.cnblogs.com/-guz/p/9695140.html
Copyright © 2011-2022 走看看