題目鏈接: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;
}