• [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;
    }
    
  • 相关阅读:
    async简单使用
    node调用phantomjs-node爬取复杂页面
    mongodb3 ubuntu离线安装(非apt-get)及用户管理
    2040-亲和数(java)
    JavaScript闭包简单理解
    nodejs构建多房间简易聊天室
    linux下安装nodejs及npm
    EventBus轻松使用
    mysql用户创建及授权
    python中json的基本使用
  • 原文地址:https://www.cnblogs.com/list1/p/10425983.html
Copyright © 2020-2023  润新知