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

    最长异或路径

    题目描述

    给定一棵(n)个点的带权树,结点下标从(1)开始到(N)。寻找树中找两个结点,求最长的异或路径。 异或路径指的是指两个结点之间唯一路径上的所有边权的异或。

    输入输出格式

    输入格式

    第一行一个整数(N),表示点数。 接下来 (n-1) 行,给出 (u,v,w) ,分别表示树上的 (u) 点和 (v) 点有连边,边的权值是 (w)

    输出格式

    一行,一个整数表示答案。

    输入输出样例

    输入样例 #1

    4
    1 2 3
    2 3 4
    2 4 6
    

    输出样例 #1

    7
    

    说明

    最长异或序列是(1-2-3),答案是 (7 (=3 ⊕ 4))

    数据范围 (1le n le 100000;0 < u,v le n;0 le w < 2^{31})

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<queue>
    #include<cmath>
    using namespace std;
    struct node{
        int v;
        int w;
        int nxt;
    }edge[2000001];
    int head[2000001];
    int cnt=-1;
    void add(int u,int v,int w){
        edge[++cnt].nxt=head[u];
        edge[cnt].v=v;
        edge[cnt].w=w;
        head[u]=cnt;
    }
    int sum[2000001];
    void dfs(int x,int fa){
        for(int i=head[x];~i;i=edge[i].nxt){
            int v=edge[i].v;
            int w=edge[i].w;
            if(v!=fa){
                sum[v]=sum[x]^w;
                dfs(v,x);
            }
        }
    }
    struct trie{
        int ch[2];
    }t[2000001];
    int tot;
    void build(int val,int x){
        for(int i=(1<<30);i;i>>=1){
            bool c=val&i;
            if(!t[x].ch[c]){
                t[x].ch[c]=++tot;
            }
            x=t[x].ch[c];
        }
    }
    int query(int val,int x){
        int ans=0;
        for(int i=(1<<30);i;i>>=1){
            bool c=val&i;
            if(t[x].ch[!c]){
                ans+=i;
                x=t[x].ch[!c];
            }
            else x=t[x].ch[c];
        }
        return ans;
    }
    int main(){
      freopen("in.in","r",stdin);
      freopen("out.out","w",stdout);
        memset(head,-1,sizeof(head));
        int n;
        scanf("%d",&n);
        for(int i=1;i<n;++i){
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            add(u,v,w);
            add(v,u,w);
        }
        dfs(1,-1);
        for(int i=1;i<=n;++i){
          build(sum[i],0);
        }
        int ans=0;
        for(int i=1;i<=n;++i){
            ans=max(ans,query(sum[i],0));
        }
        printf("%d
    ",ans);
    }
    
  • 相关阅读:
    第 6 章 Android SDK 版本与兼容
    第 5 章 第二个 activity
    第 4 章 Android 应用的调试
    第 3 章 Activity 的生命周期
    第 2 章 Android 与 MVC 设计模式
    第 1 章 Android 应用初体验
    ACM基础之线性结构:一刷 参考答案
    小马慢慢跑
    Ubuntu 利用 xinetd 限制 SSH 连接数
    C# 定制 Attribute 简单使用
  • 原文地址:https://www.cnblogs.com/scy-fisheep/p/13752934.html
Copyright © 2011-2022 走看看