The xor-longest Path ( POJ - 3764)

来源:互联网 发布:excel数据恢复打开乱码 编辑:程序博客网 时间:2024/05/17 01:46

题意: 求树上的最长xor简单路径,即以 u,v 为端点的一条简单路径,使路径上全部边权的异或和(记为f(u,v))最大。 由于 f(u,v)=f(0,u)^f(0,v),所以先求出所有节点与根0 的简单路径的异或和,然后问题就转化为 n 个数中选两个数是它们异或和最大。用字典树实现,边插入边计算。从 最高位31 到 最低位0 ,尽量取与插入的数 位上不同。(贪心!)

#include <iostream>#include <cstdio>#include <algorithm>#include <cstdlib>#include <stack>#include <vector>#include <cstring>#include <queue>#define msc(X) memset(X,-1,sizeof(X))#define ms(X) memset(X,0,sizeof(X))typedef long long LL;using namespace std;const int maxn=101010;int xorrt[maxn];struct _Edge{    int to,next,w;}edge[maxn<<1];int hd[maxn],tot;void addedge(int u,int v,int w){edge[tot].to=v;edge[tot].w=w;edge[tot].next=hd[u];hd[u]=tot++;}void dfs(int u){    for(int i=hd[u];i!=-1;i=edge[i].next)    {        int v=edge[i].to;        if(xorrt[v]==-1)            xorrt[v]=xorrt[u]^edge[i].w,            dfs(v);    }}int Tire[maxn*32][2],pos;int insert(int n){    int u=0;    for(int i=31;i>=0;i--)    {        int c=!!((1<<i)&n);        if(Tire[u][c]==0) Tire[u][c]=pos++;        u=Tire[u][c];    }    u=0;    for(int i=31;i>=0;i--)    {        int c=!((1<<i)&n);        if(Tire[u][c])            u=Tire[u][c],n|=1<<i;        else            u=Tire[u][!c],n&=~(1<<i);    }    return n;}void init(void){    msc(hd);tot=0;    ms(Tire);pos=1;    msc(xorrt);    xorrt[0]=0;}int main(int argc, char const *argv[]){    int n;    while(~ scanf("%d",&n))    {        int ans=0;        init();        for(int i=1;i<n;i++)        {            int u,v,w;            scanf("%d%d%d",&u,&v,&w);            addedge(u,v,w);            addedge(v,u,w);         }        dfs(0);        for(int i=0;i<n;i++) ans=max(ans,insert(xorrt[i]));        printf("%d\n",ans );    }    return 0;}
0 0
原创粉丝点击