最小異或生成樹Xor MST

2021-10-08 14:29:52 字數 944 閱讀 3104

1.將每個點的權值轉換成二進位制,從高位往低位依次插入01字典樹.

2.dfs遍歷該字典樹的每個結點,如果某個結點有兩個子節點,這兩個子節點的子樹分別會構成兩個連通塊,要在這兩個連通塊之間各選乙個點連邊並使它們的異或值最小,通過find函式遞迴處理這個問題.ans還要加上此時產生的二進位制位對應的值.

3.find函式中先考慮能不能同時往0子節點或同時往1子節點走,此時這兩條邊異或值為0,返回值取這兩種走法的最小值.如果不能同時往0或往1,只能乙個往1乙個往0,此時這兩條邊異或值不為零,返回值要加上此時產生的二進位制位對應的值,還要加上這兩種走法繼續向下的最小值.

時間複雜度o(30*n+(n-1)*30)

#include#include#includeusing namespace std;

typedef long long ll;

const ll inf=1e18;

const int n=200010;

int a[n];

struct node

trie[30*n+10];

int con=1;

int pow[36];

void insert(int x)

for(int i=id;i<=30;++i)

w[id++]=0;

int now=0;

for(int i=30;i>=1;--i)

else

}}ll ans=0;

ll find(int x,int y,int d)

if(trie[x].s[1]&&trie[y].s[1])

if(!f)

return res;

}void dfs(int now,int d)

int main()

dfs(0,30);

cout

}

最小異或生成樹學習筆記

最近打的區域賽模擬裡用到了最小異或生成樹 於是進行了一手學習 問題背景 有乙個序列,每個點有乙個權值 a i 取一條邊 i j 的代價是 a i xor a j 問這個圖的最小生成樹的邊權和 前置知識 trie樹 演算法原理 1 bor vka演算法 用於求解最小生成樹 做法 開始時,每個點都是乙個...

CF888G XOR MST 最小異或生成樹

cf888g trie上貪心,先左右兩邊連邊,再用一條邊的代價連起左右兩顆樹。因為內部的邊一定比跨兩棵樹的邊權笑,顯然是對的。自己瞎yy的。啟發式合併 include define ll long long using namespace std const int 2e5 7 int n,a ch...

異或最小生成樹

對於n個點的完全圖,每兩個點之間的距離等於兩點的權值的異或和,求最小生成樹 int n struct xortrie void insert ll x,int id val rt x ll answerpos int rt,int pos,ll x return rt void traceback ...