POJ 3764 The xor-longest Path
Outline of Solution: dfs calculating the root node to each of the exclusive OR and, then each converted to a binary XOR and inserted into the dictionary tree (descending inserted, because the high and more exclusive OR), and for every inquiry, try to select a different route binaries on the line. Reference to other people's code, I add comments in the code, and see.
#include<iostream>
#include<math.h>
#include<iomanip>
#include<algorithm>
#include<iostream>
#include<math.h>
#include<iomanip>
#include<algorithm>
#include<queue>
#include<cstring>
#include<string>
#include<map>
#include<stack>
#include<stdio.h>
#include<cstdio>
#include<stdlib.h>
#include<fstream>
#include<iomanip>
#pragma warning(disable:4996)
#define INF 0x3f3f3f3f
#define ll long long
#define PI acos(-1.0)
const int N = 1000010;
const int maxn = 1e9;
using namespace std;
int n,num,ans;
int dis[200005], trie[3500005][2];
struct edge {
int first,next, to, quan;
}a[200005];
void Add(int from, int to, int quan)
{
num++;//num给边标号
a[num].to = to;
a[num].quan = quan;
a[num].next = a[from].first;//类似链表的方法来记录路径,插入到根和根的next中间,新插入的成为根的next
a[from].first = num;//由于有first和next,所以节点序号和边标号不会冲突
//操作节点标号只用first,操作边标号用next,to,quan,所以不会冲突,这样少开一个数组(好像差别不大
}
void dfs(int now, int f)
{
for (int i = a[now].first; i; i = a[i].next)//每个next存着一个to和一个quan,起点都是now
{
int to = a[i].to;
int quan = a[i].quan;
if (to == f)
{
continue;
}
dis[to] = dis[now] ^ quan;//now是节点序号,不是边标号!!
dfs(to, now);
}
}
void insert(int h)
{
int now = 0;
for (int i = 30; i >= 0; i--)
{
int x = h & (1 << i);
if (x)
x = 1;
else
x = 0;
if (!trie[now][x])
trie[now][x] = ++num;//后面find中要用到链表的结构,只能这么赋值
now = trie[now][x];//关键是序号要+1
}
}
void find(int h)
{
int now = 0, tot = 0;
for (int i = 30; i >= 0; i--)
{
int x = (1 << i) & h;
if (x)
x =0;
else
x =1;
if (trie[now][x])
now = trie[now][x], tot += 1 << i;
else
now = trie[now][x ^ 1];
}
ans = max(ans, tot);
}
int main()
{
while (scanf("%d", &n) != EOF)
{
num = 0, ans = 0;
memset(a, 0, sizeof(a));
memset(trie, 0, sizeof(trie));
memset(dis, 0, sizeof(dis));
for (int i = 1; i < n; i++)
{
int x, y, z;
scanf("%d%d%d", &x, &y, &z);
x++, y++;
Add(x, y, z);
Add(y, x, z);//边可以反向走,只要不重复经过节点
}
dfs(1, 0);
num = 0;
for (int i = 1; i <= n; i++)
{
insert(dis[i]);
find(dis[i]);
}
printf("%d\n", ans);
}
}