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;
}
posted @ 2016-05-27 22:05  Krew  阅读(114)  评论(0)    收藏  举报