Codeforces 888G xor-mst Sollin algorithm for minimum spanning tree, 0-1 xor or True

Source: Internet
Author: User
Tags join time limit

G. Xor-mst time limit per test 2 seconds memory limit per test megabytes input standard input output standard output

You is given a complete undirected graph with n vertices. A number AI is assigned to each vertex, and the weight of an edge between vertices I and j are equal to Ai xor aj.

Calculate the weight of the minimum spanning tree in this graph. Input

The first line contains N (1≤n≤200000)-the number of vertices in the graph.

The second line contains n integers a1, a2, ..., A (0≤ai <)-the numbers assigned to the vertices. Output

Print One number-the weight of the minimum spanning tree in the graph. Examples input

5
1 2 3 4 5
Output
8
Input
4
1 2) 3 4
Output
8

The following:

The algorithm used in this problem is rather ancient and remote, but I have never heard of it before.

1, Sollin algorithm Introduction

Sollin (Boruvka) algorithm.

The principle is like this: just start to think of each point as a unicom component, and then expand all the Unicom components at the same time, so that at least half of the number of Unicom components are merged at once.

When the merger is done in this way, first take out a unicom component, and then from the Unicom component to the other Unicom components to find a minimum edge, and then the minimum edge two endpoints connected to the integration of the Unicom components, and then to enumerate the other components of the unicom, to ensure that each iteration of all the Unicom components are considered.

We just need to iterate over logn times.

2, Sollin algorithm in the subject of the application:

Given that the edge is an XOR operation, which is one of the routines, we first set up a 0-1 trie tree.

And then add all the dots in.

Each time we traverse a unicom component, we remove the link component from the trie, then enumerate the points inside the Unicom component, and for this point, find the smallest XOR point in the trie.

And then merge these two unicom components just fine.

Unicom components use and check set to maintain.

3. Details:

Note that it is not possible to use vectors to store the Unicom component, otherwise it will be hyper-memory.

The right approach should be:

The point according to the Unicom components he belongs to sort, so that the same Unicom component points are in a continuous section inside, processing is very convenient.

Code:

#include <bits/stdc++.h> #define CONVERT (s,i) ((s>>i) &1) using namespace std;
typedef pair<int,int> P;
const int inf = 2E9;
const int MAXN = 200007; struct trie{int frq,nxt[2];}
POOL[MAXN*31];
int cnt;
int n;
	void Insert (int s) {int cur = 0;
		for (int i = 30;i >= 0;--i) {int &pos = Pool[cur].nxt[convert (s,i)];
		if (!pos) pos = ++cnt;
		cur = pos;
	pool[cur].frq++;
	}} int Findxor (int s) {int cur = 0,ans = s;
		for (int i = 30;i >= 0;--i) {int pos = Pool[cur].nxt[convert (s,i)]; if (! (
		POS && pool[pos].frq)) pos = Pool[cur].nxt[1^convert (s,i)],ans ^= (1<<i);
	cur = pos;
} return ans;
	} void del (int s) {int cur = 0;
		for (int i = 30;i >= 0;--i) {int pos = Pool[cur].nxt[convert (s,i)];
		cur = pos;
	pool[cur].frq--;
}} int A[MAXN],PARENT[MAXN],USED[MAXN];
	int find (int x) {return x = = Parent[x]?x:parent[x] = find (Parent[x]);} int join (int x,int y) {int px = find (x);
	int py = find (y);
	if (px = = py) return 0; Parent[py] = PX
return 1;
	} bool Check () {int f = 0;
	for (int i = 1;i <= n;++i) F + = parent[i] = = i;
return F = = 1;
A long long res = 0;
P PS[MAXN];
	int main () {cnt = 0;
	cin>>n;
	for (int i = 1;i <= n;++i) parent[i] = i;
	memset (pool,0,sizeof (pool));
	for (int i = 1;i <= n;++i) scanf ("%d", &a[i]);
	Sort (a+1,a+1+n); n = Unique (a+1,a+1+n)-(a+1);
	for (int i = 1;i <= n;++i) Insert (A[i]);
		while (!check ()) {memset (used,0,sizeof (used));
		for (int i = 1;i <= n;++i) ps[i] = Make_pair (Find (i), i);
		Sort (ps+1,ps+1+n);
		int pre = Ps[1].first,last = 1;
			for (int i = 1;i <= n;++i) {int u = ps[i].second;
			if (!used[pre] && Ps[i].first = = Pre) del (A[u]);
					if (ps[i+1].first! = Pre) {if (Used[find (U)]) {for (int j = last;j <= i;j++) Insert (A[ps[j].second]);
					last = I+1;pre = Ps[last].first;
				Continue
				} Used[pre] = 1;
				int mi = INF,CV;
					for (int j = last;j <= i;++j) {int v = findxor (A[ps[j].second]); if ((V^a[ps[j].second])< mi) mi = V^A[PS[J].SECOND],CV = v;
				} res + = mi;
				for (int j = last;j <= i;++j) Insert (A[ps[j].second]);
				int PJ = Lower_bound (A+1,A+1+N,CV)-A;
				PJ = Find (PJ);
				Pre = find (U);
				if (Pre > PJ) swap (PRE,PJ);
				Join (PRE,PJ);
			Pre = Ps[i+1].first,last = i+1;
	}}} cout<<res<<endl;
return 0; }








Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.