144. 最長異或值路徑
給定乙個樹,樹上的邊都具有權值。
樹中一條路徑的異或長度被定義為路徑上所有邊的權值的異或和:
⊕ 為異或符號。
給定上述的具有n個節點的樹,你能找到異或長度最大的路徑嗎?
輸入格式
第一行包含整數n,表示樹的節點數目。
接下來n-1行,每行包括三個整數u,v,w,表示節點u和節點v之間有一條邊權重為w。
輸出格式
輸出乙個整數,表示異或長度最大的路徑的最大異或和。
資料範圍
1≤n≤1000001≤n≤100000,
0≤u,v輸入樣例:
4
0 1 3
1 2 4
1 3 6
輸出樣例:
7
樣例解釋
樣例中最長異或值路徑應為0->1->2,值為7 (=3 ⊕ 4)
題解 : 設 d[x] 表示根節點到 x 的路徑上所有邊權的 xor 值 , 顯然有:
d[x] = d[father(x) ] xor weight(x,father(x))
根據上式, 我們可以對樹dfs一遍 ,求出所有的 d[x] , 不難發現,樹上 x 到 y 的路徑上的所有邊權的 xor 結果 就等於 d[x] xor d[y].
這是根據 異或的性質( a xor a = 0 ) , "x到根 " 和" y 到根 " 這兩條路徑重疊的部分恰好抵消。 ,
問題就轉化成 了從 d[1] ~d[n] 這 n 個數中選出兩個數, 使得xor 結果最大。
#include #include #include #include using namespace std ;
const int max = 100015 ;
typedef long long ll ;
int n ;
int d[max] ;
int trie[max*32][2] ;
struct edge ;
int cnt ;
int tot = 1 ;
int vis[max*2];
edge edge[max*2] ;
int head[max*2] ;
void add(int u ,int v ,int w)
void dfs(int v )
} return ;
}void insert(int x )
p = trie[p][ch] ;
} return ;
}int query(int x)
dfs(0) ;
int res = 0 ;
for(int i = 0 ; i
cout<
return 0 ;
}
AcWing 144 最長異或值路徑
找到兩個點之間的路權值異或和最大。將無根樹扯成有根樹,將根節點到每個葉子節點的路徑異或權值處理出來存起來,然後我們可以遍歷取max,因為從根節點到兩個葉子節點的值異或起來會把中間重複路徑的異或權值消去 異或的性質,相同異或為0 所以借助trie樹就可以了。include using namespac...
AcWing 144 最長異或值路徑(Trie)
題目大意 一棵樹,邊有權值。現在定義路徑的值為路徑中邊的權值的異或值,求異或值最大的路徑。題解 從a到b路徑的異或值 a到根結點的異或值 b到根結點的異或值。這樣求出每個點到根結點的異或值,然後從n個數中選出異或值最大的數就可以。把n個數插入trie樹中做。include include inclu...
最長異或值路徑 字典樹應用
任何新型別的題,都可以轉換成自己熟悉的題來解答。就像下面的這題 給定乙個樹,樹上的邊都具有權值。樹中一條路徑的異或長度被定義為路徑上所有邊的權值的異或和 為異或符號。給定上述的具有n個節點的樹,你能找到異或長度最大的路徑嗎?輸入格式 第一行包含整數n,表示樹的節點數目。接下來n 1行,每行包括三個整...