两点注意:
首先,pop一个点now,设fath[now]为当前堆顶节点。
其次,这题不保证两军团是否merge过。
#include<iostream> #include<cstdio> #include<cstring> #define maxn 1000500 using namespace std; int n,m,w[maxn],tree[maxn][3],fath[maxn],x,y,dis[maxn]; char s[3]; bool vis[maxn]; int find(int x) { if(x!=fath[x]) fath[x]=find(fath[x]); return fath[x]; } void pushup(int x) { int ls=tree[x][1],rs=tree[x][2]; if (dis[ls]<dis[rs]) swap(tree[x][1],tree[x][2]); if (rs==0) dis[x]=0; else dis[x]=dis[rs]+1; } int merge(int a,int b) { if (a==0) return b; if (b==0) return a; if (w[a]>w[b]) swap(a,b); tree[a][2]=merge(tree[a][2],b); fath[tree[a][2]]=a; pushup(a); return a; } void pop(int x) { int ls=tree[x][1],rs=tree[x][2]; tree[x][1]=tree[x][2]=dis[x]=0; fath[ls]=ls;fath[rs]=rs; int regis=merge(ls,rs); fath[x]=regis; } void work1() { scanf("%d",&x); if (vis[x]) printf("0\n"); else { int now=find(x); printf("%d\n",w[now]); vis[now]=true; pop(now); } } void work2() { int regis; scanf("%d%d",&x,&y); if ((vis[x])||(vis[y])) return; int f1=find(x),f2=find(y); if (f1!=f2) regis=merge(f1,f2); } int main() { scanf("%d",&n); for (int i=1;i<=n;i++) { scanf("%d",&w[i]); fath[i]=i; } scanf("%d",&m); for (int i=1;i<=m;i++) { scanf("%s",s); if (s[0]=='K') work1(); else work2(); } return 0; }