NOI2002:银河英雄传说(Galaxy)
题目:http://codevs.cn/problem/1540/
分析:
首先不难想到并查集维护,但是貌似用了路径压缩就不支持查询距离操作?
实际上用带权并查集维护到根结点的距离,查询时相减一下就可以了【滑稽】
代码:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#define rep(i,x,y) for (int i=x;i<=y;i++)
#define dep(i,y,x) for (int i=y;i>=x;i--)
using namespace std;
const int maxn=30000+10;
char c;
int T,x,y,F[maxn+10],d[maxn+10],num[maxn+10];
void init() //初始化
{
rep(i,1,maxn) {F[i]=i;num[i]=1;}
memset(d,0,sizeof(d));
}
int find(int k)
{
if (F[k]==k)
return k;
else
{
int p=find(F[k]);
d[k]+=d[F[k]]; //维护到根节点距离
return F[k]=p;
}
}
void unit(int x,int y) //因为指定了节点顺序,不能用启发式合并
{
int p=find(x),q=find(y);
if (p==q) return;
F[p]=q;
d[p]=num[q];
num[q]+=num[p]; //维护当前序列战舰个数
}
int main()
{
init();
scanf("%d",&T);
while (T--)
{
c=getchar();
while ((c!='M')&&(c!='C')) c=getchar();
scanf("%d%d",&x,&y);
if (c=='M')
unit(x,y);
else
if (find(x)!=find(y))
printf("%d\n",-1);
else
printf("%d\n",abs(d[x]-d[y])-1);
}
return 0;
}

浙公网安备 33010602011771号