The longest path XORed

The longest path XORed

There is given a tree of n nodes, set \ (w [i] [j ] \) is the distance from the right edge, define a path between the i, j, which is on the right path isobutyl or all sides and, you choose any two points, minimize path distance between two points, and obtain the maximum value, \ (1≤n≤100000 \) .

solution

Tree problem, there becomes no roots roots, even better research, are usually maintained for each node to the root node, then set \ (S [i] \) represents an exclusive weights path to the root node or point i and this again dfs can maintain it, I will not appeal the superfluous.

At this time, found that for any two points i, j the distance becomes between \ (W [I] \ Wedge W [j] \) , because the same number of the same number of exclusive OR result is 0, the \ ( w [i] \ Wedge w [J] \) , precisely because of this nature, to remove the i, j from the common ancestor to the root node, and the rest are from natural distance i, j of the.

So the question becomes set \ (\ {w [i] \} \) selecting two numbers, and maximize their exclusive or, obviously as long as we maintain a trie tree, these numbers as the string 01 from a high low insertion into a trie, and then try to select for each number from trie tree from the top down to make this one the number of non-zero number can be.

Reference Code:

#include <iostream>
#include <cstdio>
#define il inline
#define ri register
#define Size 100050
using namespace std;
struct point{
    point *next;int to,w;
}*pt,*head[Size];
bool is[Size];
int dis[Size],trie[Size*31][2],tot;
void dfs(int);
il int ask(int);
il void read(int&),
    link(int,int,int),
    insert(int);
template<class free>
il free Max(free,free);
int main(){
    int n,ans(0);read(n);
    for(int i(1),u,v,w;i<n;++i)
        read(u),read(v),read(w),
            link(u,v,w),link(v,u,w);dfs(0);
    for(int i(1);i<=n;++i)
        ans=Max(ans,ask(dis[i]));
    printf("%d",ans);
    return 0;
}
template<class free>
il free Max(free a,free b){
    return a>b?a:b;
}
il int ask(int x){
    int ans(0),p(0);
    for(int i(30);i>=0;--i)
        if(trie[p][x>>i&1^1])
            p=trie[p][x>>i&1^1],
                ans|=1<<i;
        else p=trie[p][x>>i&1];
    return ans;
}
il void insert(int x){int p(0);
    for(int i(30);i>=0;--i){
        if(!trie[p][x>>i&1])
            trie[p][x>>i&1]=++tot;
        p=trie[p][x>>i&1];
    }
}
void dfs(int x){is[x]|=true,insert(dis[x]);
    for(point *i(head[x]);i!=NULL;i=i->next){
        if(is[i->to])continue;
        dis[i->to]=dis[x]^i->w,dfs(i->to);
    }
}
il void link(int u,int v,int w){
    pt=new point{head[u],v,w},head[u]=pt;
}
il void read(int &x){
    x^=x;ri char c;while(c=getchar(),c<'0'||c>'9');
    while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c^48),c=getchar();
}

Guess you like

Origin www.cnblogs.com/a1b3c7d9/p/11248071.html