[codevs 1187]Xor最大路径 Trie+贪心

来源:互联网 发布:php 去除重复的数组 编辑:程序博客网 时间:2024/05/17 04:18

问题概括:求一棵带边权的树的一条最大Xor路径的值。

首先算出所有点到根路径的xor值并保存,这样任意两点路径的xor就可以用上述值互相xor表示(异或的基本性质)。

然后用所有值建一个Trie,位数强制31。对每个值在Trie上贪心即可,就是说尽量取反。

然而这题直接在Trie树上跑贪心会wa,而且大部分点都对了,不能理解。

#include<iostream>#include<cstdio>#include<cstring>#include<vector>using namespace std;struct node{    int to,sum,fa,val;};int num=0,vis[100010]={0},value[100010];int maxans=0;vector<node> tree[100010];void dfs(int fa,int sum){    for(int i=0;i<tree[fa].size();i++){        if(tree[fa][i].to!=fa&&vis[tree[fa][i].to]==0){            value[num]=tree[fa][i].val^sum;            num++;            vis[tree[fa][i].to]=1;            tree[fa][i].sum=tree[fa][i].val^sum;            tree[fa][i].fa=fa;            dfs(tree[fa][i].to,tree[fa][i].val^sum);        }    }}struct Trie{    int ch[4200010][2];    int val[4200010];    int sz;    Trie(){        sz=1;        memset(ch[0],0,sizeof(ch[0]));    }    void insert(int s,int v){        int u=0;        int k=0;        int bit[32]={0};        while(s>0){            bit[k++]=s&1;            s>>=1;        }        for(int i=30;i>=0;i--){            int c=bit[i];            if(!ch[u][c]){                memset(ch[sz],0,sizeof(ch[sz]));                val[sz]=0;                ch[u][c]=sz++;            }        u=ch[u][c];        }        val[u]=v;    }    void solve(){        for(int i=0;i<num;i++){            int tmp=value[i];            int now=0;            int ans=0;            for(int j=30;j>=0;j--){                int bit=(tmp&(1<<(j)))>>j;                if(ch[now][1-bit]>0){                    ans=ans|((1-bit)<<j);                    now=ch[now][1-bit];                }                else if(ch[now][bit]>0){                    ans=ans|(bit<<j);                    now=ch[now][bit];                }            }            if((ans^tmp)>maxans)maxans=(ans^tmp);        }    }    void print(){        for(int i=0;i<sz;i++)cout<<i<<" "<<ch[i][0]<<" "<<ch[i][1]<<endl;    }};Trie t;int main(){    int n;    scanf("%d",&n);    int x,y,z;    for(int i=1;i<=n-1;i++){        scanf("%d%d%d",&x,&y,&z);        node tmp;        tmp.sum=0;        tmp.val=z;        tmp.to=y;        tree[x].push_back(tmp);        tmp.to=x;        tree[y].push_back(tmp);    }    vis[1]=1;    dfs(1,0);    for(int i=0;i<num;i++)t.insert(value[i],1);    t.insert(0,1);    t.solve();    printf("%d\n",maxans);    return 0;}


0 0