并查集
1 - 畅通工程
Problem:
思路
可以用并查集解题,就是所说的集合,还有一个稍微繁琐的方式就是基于邻接矩阵的图的深度优先遍历
Code
#include<stdio.h>
#include<string.h>
#define N 1010
//集合,下标是元素值,这里值域就是结点数
int a[N];
int find(int x) {
//如果x不是根节点,那么就向上找,并且是改进后的Find操作,减少了树高
if(a[x] >= 0) {
return a[x] = find(a[x]);
}
return x;
}
void unite(int x, int y) {
//分别查找两个端点所在的集合
x = find(x), y = find(y);
//如果不在一个集合中,就把两个集合合并,这样指定为y为集合根节点
if (x != y) {
//维护集合中的元素个数
a[y] += a[x];
a[x] = y;
}
}
int main() {
int n, m;
scanf("%d %d", &n, &m);
int i;
for (i = 1; i <= n; i++) a[i] = -1;
for (i = 0; i < m; i++) {
int u, v;
scanf("%d %d", &u, &v);
unite(u, v);
}
int count = 0;
for (i = 1; i <= n; i++) {
if (a[i] < 0) {
count++;
// printf("%d ", (-1) * a[i]);
}
}
printf("%d\n", count - 1);
return 0;
}