HDOJ 1512 Monkey King -- 左偏樹

題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1512

分析:左偏樹應用。在結點中加入了parent指針和id字段,這樣可以代替並查集。關於左偏樹可以參考黃源河的論文《左偏樹的特點及其應用》。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define mp make_pair
#define X first
#define Y second
#define MEMSET(a, b) memset(a, b, sizeof(a))
using namespace std;

typedef unsigned int ui;
typedef long long ll;
typedef unsigned long long ull;
typedef pair pii;
typedef vector vi;
typedef vi::iterator vi_it;
typedef map mii;
typedef priority_queue pqi;
typedef priority_queue, greater > rpqi;
typedef priority_queue pqp;
typedef priority_queue, greater > rpqp;

typedef struct node
{
	int key;
	int dist;
	int id;
	node *left;
	node *right;
	node *parent;
} *pnode;

const int MAX_N = 100000 + 2;
pnode mk[MAX_N];
pnode hd[MAX_N];

class LeftistTree
{
	public:
	pnode merge(pnode a, pnode b) {
		if (a == NULL) {
			return b;
		}
		if (b == NULL) {
			return a;
		}
		if (a->key < b->key) {
			swap(a, b);
		}
		a->right = merge(a->right, b);
		a->right->parent = a;
		if (a->left == NULL || a->left->dist < a->right->dist) {
			swap(a->right, a->left);
		}
		if (a->right == NULL) {
			a->dist = 0;
		}
		else {
			a->dist = a->right->dist + 1;
		}
		a->parent = NULL;
		return a;
	}
	
	int get_max(const pnode &a) {
		return a->key;
	}
	
	void decrease_key(pnode a) {
		pii maxv = del_max(a);
		ins(a, maxv.X >> 1, maxv.Y);
	}
	
	pnode new_node(int key, int id) {
		pnode p = new node();
		p->left = p->right = p->parent = NULL;
		p->key = key;
		p->id = id;
		p->dist = 0;
		return p;
	}
	
	pnode get_root(pnode p) {
		while (p->parent != NULL) {
			p = p->parent;
		}
		return p;
	}
	
	void clear_tree(pnode root) {
		if (root == NULL) {
			return;
		}
		clear_tree(root->left);
		clear_tree(root->right);
		delete root;
	}
	
	private:
	pii del_max(pnode &a) {
		pii ret = mp(a->key, a->id);
		pnode b = a;
		a = merge(a->left, a->right);
		delete b;
		return ret;
	}
	
	void ins(pnode &a, int key, int id) {
		mk[id] = new_node(key, id);
		a = merge(a, mk[id]);
	}
};

int main(int argc, char *argv[])
{
//	freopen("D:\\in.txt", "r", stdin);
	int n, m, i, k, a, b;
	LeftistTree lft;
	while (cin >> n) {
		for (i = 1; i <= n; ++i) {
			scanf("%d", &k);
			mk[i] = lft.new_node(k, i);
		}
		cin >> m;
		while (m--) {
			scanf("%d%d", &a, &b);
			pnode h1 = lft.get_root(mk[a]), h2 = lft.get_root(mk[b]);
			if (h1 == h2) {
				puts("-1");
			}
			else {
				lft.decrease_key(h1);
				lft.decrease_key(h2);
				h1 = lft.get_root(mk[a]);
				h2 = lft.get_root(mk[b]);
				pnode h = lft.merge(h1, h2);
				printf("%d\n", lft.get_max(h));
			}
		}
		
		int cnt = 0;
		for (i = 1; i <= n; ++i) {
			if (mk[i] != NULL && mk[i]->parent == NULL) {
				hd[cnt++] = mk[i];
			}
		}
		for (i = 0; i < cnt; ++i) {
			lft.clear_tree(hd[i]);
		}
	}
	
	return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章