您的位置:首页 > 其它

hdoj 1232 畅通工程

2012-08-09 19:30 399 查看
裸的并查集,把每个集合看成一个点,然后点的总和减1就是道路条数,比如两个点之间连通最少需要1条路;

#include <stdio.h>

int set[1001];

int find(int n)//寻找祖先,类似双亲树
{
while (set
!= n)//o(logN)
n = set
;
return n;
}

void merge(int a, int b)//合并集合
{
b = find(b);
set[b] = a;//用a的值覆盖b祖先的值,a的祖先就变成了b的祖先了
}

int main()
{
int n, m;
while (true)
{
scanf("%d", &n);
if (!n)
break;
scanf("%d", &m);
int i, t1, t2;
for (i = 1; i <= n; i++)//初始化很重要,把每个数都作为自己的祖先,换句话说有n个城镇就有n个祖先(集合)
set[i] = i;
for (i = 0; i < m; i++)
{
scanf("%d %d", &t1, &t2);
if (find(t1) != find(t2))//判断是否为同一祖先不是的话说明不是同一集合,合并两个集合
merge(t1, t2);
}
int count = -1;
for (i = 1; i <= n; i++)//如果下标i和对应数组值一样,set[i]就是一个集合的祖先
if (set[i] == i)
count++;

printf("%d\n", count);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: