This question is very simple. Find a path in a tree to make it different or right (that is, the weights of all edges in the path are different
Or up) the maximum.
This question takes two steps. The first step is to assume that the root is node 0, find the difference or distance from the root to other nodes, and save it in the array xor,
You can use this dfs. Then, xor [I] ^ xor [j] can represent the path from node I to node j. The conclusion is as follows.
If the path between I and j passes through the root node, the above conclusion is correct. If the path does not pass through the root
Xor [I] and xor [j] must protect the same sub-path from the root to a node. According to the different or nature, this sub-path will
This conclusion is true...
The second step is enumeration. xor [I] ^ xor [j] maximizes the result. If it is directly violent, the square algorithm will definitely time out.
Since each value can be expressed as a binary system, if other xor values are saved in the dictionary tree, use the current xor [I] To Go To The dictionary tree.
The exclusive or maximum value can be found once.
In addition, because the number of points in the tree is too large, we can only use the adjacent table, and use the vector to simulate the adjacent table to time out...
Changed to static linked list...
The Code is as follows:
# Include <stdio. h>
# Include <string. h>
# Include <algorithm>
# Include <vector>
Using namespace std;
Const int MAX = 100010;
Int nXor [MAX];
Bool bVis [MAX];
Int nFirst [MAX];
Struct Edge
{
Int nE;
Int nW;
Int nNext;
};
Edge egs [MAX * 2];
Struct Node
{
Node * pSons [2];
};
Node nodes [MAX * 32];
Node * pRoot = & nodes [0];
Int nNew;
Void GetBCode (int nL, int * nBCode, int & nLen)
{
NLen = 0;
While (nLen <= 30)
{
NBCode [nLen ++] = nL % 2;
NL> = 1;
}
Reverse (nBCode, nBCode + nLen );
}
Void Insert (int nL)
{
Int nLen = 0;
Int I = 0;
Int nBCode [32];
GetBCode (nL, nBCode, nLen );
Node * pNode = pRoot;
While (I <nLen)
{
If (pNode-> pSons [nBCode [I])
{
PNode = pNode-> pSons [nBCode [I];
}
Else
{
Memset (nodes + nNew, 0, sizeof (nodes [nNew]);
PNode-> pSons [nBCode [I] = nodes + nNew;
PNode = nodes + nNew;
++ NNew;
}
++ I;
}
}
Int FindMax (int nL)
{
Int nLen = 0;
Int nAns = 0;
Int I = 0;
Int nBCode [32];
Node * pNode = pRoot;
GetBCode (nL, nBCode, nLen );
While (I <nLen)
{
Int nBest = (nBCode [I] = 0? 1: 0 );
Int nBad = (nBCode [I] = 0? 0: 1 );
If (pNode-> pSons [nBest])
{
NAns = 2 * nAns + nBest;
PNode = pNode-> pSons [nBest];
}
Else if (pNode-> pSons [nBad])
{
NAns = 2 * nAns + nBad;
PNode = pNode-> pSons [nBad];
}
Else break;
++ I;
}
Return nAns ^ nL;
}
Void Dfs (int nV, int nL)
{
NXor [nV] = nL;
BVis [nV] = true;
For (int e = nFirst [nV]; e! =-1; e = egs [e]. nNext)
{
If (! BVis [egs [e]. nE])
{
Dfs (egs [e]. nE, nL ^ egs [e]. nW );
}
}
}
Int main ()
{
Int nN;
Int nU, nV, nW;
While (scanf ("% d", & nN) = 1)
{
For (int I = 0; I <nN; ++ I) nFirst [I] =-1;
For (int I = 1, j = 0; I <nN; ++ I)
{
Scanf ("% d", & nU, & nV, & nW );
Egs [j]. nE = nV;
Egs [j]. nW = nW;
Egs [j]. nNext = nFirst [nU];
NFirst [nU] = j ++;
Egs [j]. nE = nU;
Egs [j]. nW = nW;
Egs [j]. nNext = nFirst [nV];
NFirst [nV] = j ++;
}
Memset (bVis, false, sizeof (bool) * nN );
Dfs (0, 0 );
Memset (& nodes [0], 0, sizeof (Node ));
NNew = 1;
Int nAns = 0;
For (int I = 0; I <nN; ++ I)
{
NAns = max (nAns, FindMax (nXor [I]);
Insert (nXor [I]);
}
Printf ("% d \ n", nAns );
}
Return 0;
}