hdu 1232解题报告 可供初步了解、回顾并査集

这是一个简单的并査集运用,每次案例开始,我们按照输入的N城市个数初始化:

初始化过程为,1到N的父亲节点为本身,1到N的rank深度为0,但是我们把rank[0]

作为要修建的道路数,初始化为N-1,比如我们初始化N为3的情况,rank[0]=2,一开始只要

修建两条路.....然后就是按照M输入M组联通城市,每次就和并一次,合并最后,我们就把

rank[0]减一,因为合并了两个城市之后,道路就少了一条。

基于这个题目,推荐一个一样的题目,就是poj2524 宗教的个数

这个链接是关于并査集的学习,我是一个小白,开始就是看了这里 http://wenku.baidu.com/view/f55a0d26aaea998fcc220e8f.html

下面是代码

#include

int father[1005];//记录父亲节点
int rank[1005];//记录次节点的深度

void init(int n)
{
 for(int i=1;i<=n;i++)
 {
  father[i]=i;
  rank[i]=0;
 }
 rank[0]=n-1;
}

int find(int x)
{
 if(x!=father[x])
  father[x]=find(father[x]);
 return father[x];
}

void Union(int x,int y)
{
 if(x == y)
  return ;
 if(rank[x] > rank[y])//将深度浅的合并入深度大的集合中 可看链接 http://zh.wikipedia.org/zh-cn/%E5%B9%B6%E6%9F%A5%E9%9B%86
  father[y]=x;
 else
 {
  father[x]=y;
 }
 if(rank[x] == rank[y])
  rank[y]++;
 rank[0]--;//合并了一次,道路数就减一
}

int main()
{
 int N,M;
 int a,b;
 while(scanf("%d",&N),N)
 {
  init(N);
  scanf("%d",&M);
  while(M--)
  {
   scanf("%d%d",&a,&b);
   Union(find(a),find(b));
  }
  printf("%d\n",rank[0]);
 }
 return 0;
}

 


 

你可能感兴趣的:(数据结构)