1159. 【NOI2002】银河英雄说(并查集)
2017-08-21 12:45
260 查看
The link :
https://jzoj.net/junior/#main/show/1826Problem
给定T条指令,每次指令有合并,询问两种操作,如果是合并,就把对应的两条边合并到一个集合中,如果是询问,则询问两点是否在同一个集合,如果是,输出两点之间的距离,否则输出-1.Data constraint
1<=T<=500,0001<=i , j<=30000
Solution
注意这道题的一个关键,这是一条链,虽然还是得用路径压缩,但不能按秩合并,每次一定是连到末尾,那么这样子我们只需要维护一个深度和一个高度,每次在找父亲时更新即可.深度:从根节点往下的路径数.
高度:从一个节点到叶节点的最长路径数.
所以每次拿高度去更新深度即可.
#include <iostream> #include <cstdio> #include <cstring> #define Maxn 500001 using namespace std; char ch[1]; int T,i,x,y,xx,yy,fa[Maxn],sum[Maxn],deep[Maxn]; int abs(int x) { if (x>0) return x; else return -x; } int getfather(int x) { if (fa[x]==0) return x; int get=getfather(fa[x]); deep[x]+=deep[fa[x]],fa[x]=get; return get; } void merge(int x,int y) { xx=getfather(x),yy=getfather(y); fa[xx]=yy,deep[xx]+=sum[yy],sum[yy]+=sum[xx]; } void Query(int x,int y) { xx=getfather(x),yy=getfather(y); if (xx!=yy) printf("-1\n"); else printf("%d\n",abs(deep[x]-deep[y])-1); } int main() { scanf("%d",&T); for (i=1;i<=30000;i++) sum[i]=1; for (i=1;i<=T;i++) { scanf("%s %d %d",ch,&x,&y); if (ch[0]=='M') merge(x,y); else Query(x,y); } }
相关文章推荐
- noi2002 银河英雄传说 (并查集处理路径)
- [题解] NOI2002 银河英雄传说 (并查集)
- NOI 2002 Day1 T1 银河英雄传说【并查集】
- 洛谷 1196 [NOIP2002] 银河英雄传说 并查集
- 【NOI2002】银河英雄说
- COGS 260. [NOI2002] 银河英雄传说 解题报告
- 解题报告 The cubes(即 银河英雄传说 NOI 2002)
- 银河英雄传说 洛谷1196 并查集
- NOI2002 银河英雄传说(并查集)
- 银河英雄传说 洛谷1196 并查集
- Noi2002 银河英雄传说(并查集)
- [NOI 2002] 银河英雄传说 (带权并查集)
- P1196 & ssl1225-银河英雄传说【图论,并查集】
- 银河英雄传说 洛谷1196 并查集
- SSL 1255_银河英雄传说_并查集
- 加权并查集(银河英雄传说,Cube Stacking)
- 并查集——nkoj1206【NOI2002 Day1 T1】银河英雄传说
- 银河英雄传说 洛谷1196 并查集
- 银河英雄传说 洛谷1196 并查集
- [NOI2002]银河英雄传说(并查集)