额 并查集 用启发式搜索
但是维护里面最大值时是要用优先队列的 一开始傻傻的以为用一个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 */