zoukankan      html  css  js  c++  java
  • [POJ3764]最长异或路径

    Description:

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

    Hint:

    (n<=10^5)

    Solution:

    真是01Trie傻逼题,居然想了好久
    瓶颈在于如何找出所有的点到根节点的异或值中异或起来最大的两个
    考虑将每个点到根节点的异或值插入Trie,再同样地查询一次就行了

    #include<bits/stdc++.h>
    using namespace std;
    const int mxn=1e7+5;
    struct ed {
    	int to,nxt,w;
    }t[mxn<<1];
    int n,cnt,a[mxn],hd[mxn];
    
    inline void add(int u,int v,int w) {
    	t[++cnt]=(ed) {v,hd[u],w}, hd[u]=cnt;
    }
    
    namespace trie {
    	int tot,ch[mxn][2];
    	void ins(int x) {
    		int u=0;
    		for(int i=30;i>=0;--i) {
    			int is=x>>i&1;
    			if(!ch[u][is]) ch[u][is]=++tot;
    			u=ch[u][is];
    		}
    	}
    	int query(int x) {
    		int u=0,ans=0;
    		for(int i=30;i>=0;--i) {
    			int is=(x>>i&1)^1;
    			if(ch[u][is]) u=ch[u][is],ans+=1<<i;
    			else u=ch[u][is^1];
    		}
    		return ans;
    	}
    }
    using namespace trie;
    
    void dfs(int u,int fa,int w) 
    {
    	a[u]=w;
    	for(int i=hd[u];i;i=t[i].nxt) {
    		int v=t[i].to;
    		if(v==fa) continue ;
    		dfs(v,u,w^t[i].w);
    	}
    }
    
    int main()
    {
    	scanf("%d",&n); int u,v,w;
    	for(int i=1;i<n;++i) {
    		scanf("%d%d%d",&u,&v,&w);
    		add(u,v,w);
    		add(v,u,w);
    	}
    	dfs(1,0,0); int ans=0;
    	for(int i=1;i<=n;++i) ins(a[i]);
    	for(int i=1;i<=n;++i) ans=max(ans,query(a[i]));
    	printf("%d",ans);
    	return 0;
    }
    
  • 相关阅读:
    jdk动态代理底层实现
    spring-FactoryBean
    大型网站技术架构 核心原理与案例分析 pdf
    实战JAVA虚拟机 JVM故障诊断与性能优化 pdf
    《实战Java高并发程序设计》pdf
    mysql-注意点
    Json入门
    inflate, findViewById与setContentView的区别与联系
    提高编程能力的7条建议
    JDBC之一:JDBC快速入门
  • 原文地址:https://www.cnblogs.com/list1/p/10425983.html
Copyright © 2011-2022 走看看