hdu 1512 左偏树
2016-12-31 19:55
260 查看
题意大概是有n只猴子,m次矛盾,a和b产生矛盾时,如果他们不认识,就会找各自认识中最强壮的猴子打架,然后打架的猴子权值减半,这两拨猴子就互相认识了,成了一群猴子,每次求合成一群后的最大权值。
#include<iostream> #include<cstdio> #define maxn 100001 using namespace std; int f[maxn]; int find(int x) { int r=x; while(f[r]!=r)r=f[r]; while(x!=r) { f[x]=r; x=f[x]; } return r; } int val[maxn],dis[maxn]; int l[maxn],r[maxn]; int merge(int x,int y) { if(x*y==0) return x+y; if(val[x]<val[y]) swap(x,y); r[x]=merge(r[x],y); f[r[x]]=x; if(dis[r[x]]>dis[l[x]]) swap(r[x],l[x]); if(r[x])dis[x]=dis[r[x]]+1; else dis[x]=0; return x; } int del(int x) { int L=l[x],R=r[x]; f[L]=L;f[R]=R; dis[x]=l[x]=r[x]=0; return merge(L,R); } void solve(int x,int y) { int rx=del(x); val[x]/=2; x=merge(rx,x); int ry=del(y); val[y]/=2; y=merge(ry,y); printf("%d\n",val[merge(x,y)]); } int main() { int n; while(scanf("%d",&n)!=EOF) { for(int i=1;i<=n;i++) { f[i]=i; dis[i]=l[i]=r[i]=0; scanf("%d",&val[i]); } int m; scanf("%d",&m); int u,v,fu,fv; for(int i=1;i<=m;i++) { scanf("%d%d",&u,&v); int fu=find(u),fv=find(v); if(fu!=fv) solve(fu,fv); else puts("-1"); } } return 0; }
相关文章推荐
- HDU 1512 可并堆(左偏树) 解题报告
- hdu1512 & zoj2334Monkey King(左偏树 + 并查集)
- hdu-1512 Monkey King [并查集+左偏树]
- hdu 1512 Monkey King 左偏树
- HDU 1512 Monkey King(左偏树)
- Hdu 1512 Monkey King 左偏树 解题报告
- HDU 1512 Monkey King ——左偏树
- HDU 1512 Monkey King(左偏树模板题)
- HDU1512 Monkey King【并查集+左偏树】
- HDU 1512 Monkey King 并查集+左偏树
- 【HDU】1512 Monkey King 左偏树
- HDU 1512 HDOJ 1512 Monkey King ( 左偏树 ) ACM 1512 IN HDU
- hdu 1512 Monkey King (左偏树可并堆 并查集)
- hdu 1512 左偏树
- HDU 1512 Monkey King(左偏树)
- 数据结构(左偏树):HDU 1512 Monkey King
- 【左偏树】HDU 1512/ZOJ 2334
- 【左偏树】HDU1512-Monkey King
- HDU 1512 浅谈可并堆即左偏树模板及并查集灵活应用
- hdu1512 & zoj2334Monkey King(左偏树 + 并查集)