这是一个简单的并査集运用,每次案例开始,我们按照输入的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<stdio.h> 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; }