完全圖的最小生成樹


Description

給你一張完全圖,每一個點有一個點權為 \(a[i]\),邊 \((u,v)\) 的邊權為 \(a[u]\) \(xor\) \(a[v]\),求最小生成樹的邊權和.

solution

正解:trie樹+貪心
考慮優化kruskal的過程,我們找出邊權最小的且邊的兩邊沒有連通的邊,選擇連接,方法是在trie樹上貪心,首先我們對所有的點建立trie樹,然后考慮怎么樣連邊最優,容易發現,一定是選擇二進制下交最多的兩個點,那么一定對應trie樹上的一個前綴,所以我們只需要dfs trie樹,自底向上合並即可,考慮枚舉左右子樹中size小的,在另一棵子樹上遍歷求得異或最小值,啟發式合並的復雜度是 \(O(n*logn)\) 的,加上trie樹的操作,總復雜度為 \(O(n*log2n)\)

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#define RG register
#define il inline
#define iter iterator
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
using namespace std;
typedef long long ll;
const int N=4000005;
inline int gi(){
	RG int str=0;RG char ch=getchar();
	while(ch>'9' || ch<'0')ch=getchar();
	while(ch>='0' && ch<='9')str=(str<<1)+(str<<3)+ch-48,ch=getchar();
	return str;
}
int n,rt=0,bin[30],sz[N],ls[N],rs[N],totnode=0;
ll ans=0;

il void ins(int &x,int v,int d){
	if(!x)x=++totnode;
	if(d==-1){sz[x]=1;return ;}
	if(bin[d]&v)ins(rs[x],v,d-1);
	else ins(ls[x],v,d-1);
	sz[x]=sz[ls[x]]+sz[rs[x]];
}

il int qry(int x,int v,int d){
	if(d==-1)return 0;
	if(v&bin[d]){
		if(rs[x])return qry(rs[x],v,d-1);
		return qry(ls[x],v,d-1)+bin[d];
	}
	else{
		if(ls[x])return qry(ls[x],v,d-1);
		return qry(rs[x],v,d-1)+bin[d];
	}
}

il int merge(int x,int y,int d,int val,int sd){
	if(d==-1)return qry(y,val,sd);
	int ret=1<<30;
	if(ls[x])ret=min(ret,merge(ls[x],y,d-1,val,sd));
	if(rs[x])ret=min(ret,merge(rs[x],y,d-1,val+bin[d],sd));
	return ret;
}

il void dfs(int x,int d){
	if(d==-1)return ;
	if(ls[x])dfs(ls[x],d-1);
	if(rs[x])dfs(rs[x],d-1);
	if(!ls[x] || !rs[x])return ;
	int l=ls[x],r=rs[x];
	if(sz[l]>sz[r])swap(l,r);
	ans+=merge(l,r,d-1,0,d-1)+bin[d];
}

void work()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)ins(rt,gi(),29);
	dfs(rt,29);
	cout<<ans<<endl;
}

int main()
{
	bin[0]=1;for(int i=1;i<=29;i++)bin[i]=bin[i-1]<<1;
	work();
	return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM