额 并查集 用启发式搜索
但是维护里面最大值时是要用优先队列的 一开始傻傻的以为用一个4个位置的数组就够了 觉得第一大的决斗完后后要么第一要么第二 真tm是智障。。。
额。。。依稀记得新生赛初赛的时候犯过差不多的智商错误 那时也是应该用优先队列的
象征性贴个代码:
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <bitset>
#include <vector>
#pragma comment(linker, "/STACK:1024000000,1024000000")
#define inf -(0x7fffffff);
using namespace std;
const int maxn=100005;
priority_queue<int>qu[maxn];
int a[maxn],order[10],m,n;
int mx1[maxn],mx2[maxn],f[maxn],h[maxn];
int find(int x)
{
if(f[x]!=x) f[x]=find(f[x]);
return f[x];
}
/*void arrange(int x,int y,int p,int q)
{
memset(order,0,sizeof(order));
mx1[q]/=2;
mx1[p]/=2;
order[1]=mx1[q];
order[2]=mx1[p];
order[3]=mx2[q];
order[4]=mx2[p];
sort(order+1,order+1+4);
}*/
int qfsunion(int x,int y)
{
x=find(x),y=find(y);
if(x==y) return -1;
int sx=qu[x].top();
qu[x].pop();
sx/=2;
int sy=qu[y].top();
qu[y].pop();
sy/=2;
if(qu[x].size()>qu[y].size()) swap(x,y);
f[x]=y;
while(!qu[x].empty())
{
int nn=qu[x].top();
qu[x].pop();
qu[y].push(nn);
}
qu[y].push(sx);
qu[y].push(sy);
return qu[y].top();
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
for(int i=1;i<=n;i++)
while(!qu[i].empty()) qu[i].pop();
memset(a,0,sizeof(a));
memset(h,0,sizeof(h));
for(int i=1; i<=n; i++)
{
scanf("%d",&a[i]);
f[i]=i;
qu[i].push(a[i]);
//mx1[i]=a[i];
//mx2[i]=inf;
}
scanf("%d",&m);
while(m--)
{
int x,y;
scanf("%d%d",&x,&y);
printf("%d\n",qfsunion(x,y));
}
}
return 0;
}
/*
7
1 5 37 3 4 2 5
5
1 3
18
2 5
2
3 4
9
2 7
2
6 7
2
*/