zoj 1789The Suspects 并查集
2011-08-09 16:44
204 查看
哈哈,第一个并查集终于写出来了,虽然从昨天看到现在,不现在才完全搞清楚过程并第一次用代码实现,好兴奋
#include<stdio.h> typedef struct //定义树节点 ,本题中,集合的名字用代表人的数字 ,node[3]代表代号为三人的人所在的树节点 { int father; int size; }xx; xx node[30002]; int find(int x) //函数,用来返回节点x所在树的树根 { while(x!=node[x].father) //如果 节点x的父节点不等于x,那么把x的父节点赋给x,继续找 x=node[x].father; return x; } void Union(int x,int y) //函数,合并两个集合,两棵树 { int a=find(x),b=find(y); node[x].father=a; //此步骤会让树变成只有根和叶的形式,即只有两层 node[y].father=b; if(a<b){ node[a].size+=node[b].size; //和并到根小的树上(集合上) node[b].father=a; } if(a>b){ node[b].size+=node[a].size; node[a].father=b; } } int main() { int m,n,k,i,j,x,y; while(scanf("%d%d",&n,&m)&&(n!=0||m!=0)){ for(i=0;i<n;i++){ node[i].father=i; //把每个节点的根初始化为自己,大小初始化为1 node[i].size=1; //初始化后,每个节点都是一棵树 ,通过后面的操作不断地把树合并 } for(i=0;i<m;i++){ //依次把每一组的人合并成一个集合 scanf("%d",&k); scanf("%d",&x); //期间,如果一个元素再次出现,会把同时包含 这个元素的两个集合合并,依次进行 for(j=1;j<k;j++){ scanf("%d",&y); Union(x,y); } } printf("%d\n",node[0].size); } return 0; }
相关文章推荐
- ZOJ 3261 Connections in Galaxy War 反向用并查集
- ZOJ ~ 3261 ~ Connections in Galaxy War (逆序并查集 + map)
- ZOJ_3811_Untrusted Patrol(并查集)
- zoj 3963 Heap Partition(并查集,贪心,二分)
- ACM zoj 1789(并查集实现)
- ZOJ2334 Monkey King 并查集 STL
- zoj 3321 Circle【并查集】
- ZOJ 3649 倍增法DP、树链剖分、tarjan并查集
- ZOJ-3261(并查集续路径压缩,灵活应用)
- zoj 3659 并查集
- ZOJ-3261 Connections in Galaxy War 并查集 离线操作
- ZOJ 3321 Circle【并查集】
- zoj 3789 并查集
- ZOJ 3261 /哈理工OJ 1913 Connection in War(逆向并查集)(STL应用)
- zoj2334 Monkey King , 并查集,可并堆,左偏树
- ZOJ-3261(Connections in Galaxy War)——并查集
- zoj 3811||牡丹江网赛 c题 并查集
- ZOJ 3261 Connections in Galaxy War (并查集)
- ZOJ 3789 齿轮操作 带权并查集
- zoj The Suspects 并查集