hdu1232问题:
首先在地图上给你若干个城镇,这些城镇都可以看作点,然后告诉你哪些对城镇之间是有道路直接相连的。最后要解决的是整幅图的连通性问题。比如随意给你两个点,让你判断它们是否连通,或者问你整幅图一共有几个连通分支,也就是被分成了几个互相独立的块。像畅通工程这题,问还需要修几条路,实质就是求有几个连通分支。如果是1个连通分支,说明整幅图上的点都连起来了,不用再修路了;如果是2个连通分支,则只要再修1条路,从两个分支中各选一个点,把它们连起来,那么所有的点都是连起来的了;如果是3个连通分支,则只要再修两条路……
输入:
第一行n,m。n表示城镇个数,m为道路数。
下面m行为各条道路与哪两个城镇相连。
4 2
1 3
4 3
输出:
1
#include <bits/stdc++.h>
using namespace std;
int pre[1000];
int find(int x)
{
int r = x;
while (pre[r] != r)//寻根
r = pre[r];
int i = x, j;
while (i != r)//压缩路径
{
j = pre[i];
pre[i] = r;
i = j;
}
return r;
}
//递归写法
int find_digui(int x)
{
if (x = pre[x])return x;
return pre[x] = find_digui(pre[x]);
}
void join(int x, int y)//给城镇修路,使两个连通分量相通
{
int fx = find(x), fy = find(y);
if(fx!=fy)
pre[fx] = fy;
}
int main()
{
int n, m;
scanf("%d%d", &n, &m);
for (int i = 0; i < n; i++)
pre[i] = i;
while (m--)
{
int i, j;
scanf("%d%d", &i, &j);
join(i, j);
}
int root[1000];//用来标记是否是根节点
memset(root, 0, sizeof(root));
for (int i = 1; i <= n; i++)
root[find(i)] = 1;
int ans = 0;
for (int i = 1; i <= n; i++)
if (root[i])
ans++;
printf("%d\n", ans - 1);
return 0;
}