pojThe xor-longest Path(trie树)

来源:互联网 发布:美国读博士条件知乎 编辑:程序博客网 时间:2024/05/16 13:43

刚刚知道一条性质:a^b=(a^c)^(b^c)。于是两点之间的异或值为其分别到根节点的异或值的异或。

用dfs求出每个点到根节点的异或值,并把每个值放在trie树上。注意:要从高位向低位建。

要使异或值最大,异或值为111...1,e.g.10101^01010=11111  ^-^

#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;#define inf 100005struct node{int to,next,val;}edge[inf<<1];int head[inf];int cnt;void add(int f,int t,int v){edge[cnt].to=t;edge[cnt].val=v;edge[cnt].next=head[f];head[f]=cnt++;}int n;int dis[inf],vis[inf];void dfs(int x,int w)//求每个点到根节点的异或{dis[x]=w;vis[x]=1;for(int i=head[x];i!=-1;i=edge[i].next){int to=edge[i].to;if(vis[to])continue;dfs(to,w^edge[i].val);}}struct trie{int next[3];}t[inf<<8];int L;void insert(int x)//建树{int a,p=0;for(int i=30;i>=0;i--){a=x&(1<<i)?1:0;if(!t[p].next[a])//判断这位上有没有出现过这个数{t[p].next[a]=++L;//新建t[L].next[0]=t[L].next[1]=0;//初始化}p=t[p].next[a];//向下移一位}}int find(int x){int a,p=0,w=0;for(int i=30;i>=0;i--){a=x&(1<<i)?0:1;//我们要找与这一位相反的数if(t[p].next[a]){w|=(1<<i);//找到了就加上p=t[p].next[a];}else{p=t[p].next[!a];}}return w;}void init(){memset(head,-1,sizeof(head));memset(dis,0,sizeof(dis));memset(vis,0,sizeof(vis));cnt=0;L=0;}int main(){while(scanf("%d",&n)!=EOF){init();for(int i=1;i<n;i++){int a,b,c;scanf("%d %d %d",&a,&b,&c);add(a,b,c);add(b,a,c);}dfs(0,0);t[0].next[0]=t[0].next[1]=0;int ans=0;for(int i=0;i<n;i++){insert(dis[i]);int u=find(dis[i]);ans=max(ans,u);}printf("%d\n",ans);}}


0 0
原创粉丝点击