HDU 1232 畅通工程 [并查集]
http://acm.hdu.edu.cn/showproblem.php?pid=1232
Description
给N个城市,再给出M条关系,表示两者是否连通
问
再修几条路,使他们全部连通
Algorithm
并查集
最后连通块数量(count)为1,表示全部连通,如果count > 1,count - 1就是要添加的路数数量
Code
C++
#include <cstdio>
#include <iostream>
using namespace std;
const int MAXN = 1000;
int n, m, count;
int id[MAXN];
int sz[MAXN];
void init()
{
for (int i = 0; i < n; i++) {
id[i] = i;
sz[i] = 1;
}
count = n;
}
int find(int p)
{
while (p != id[p]) p = id[p];
return p;
}
void unite(int p, int q)
{
int i = find(p);
int j = find(q);
if (i == j) return;
if (sz[i] > sz[j]) {
id[j] = i;
sz[i] += sz[j];
}
else {
id[i] = j;
sz[j] += sz[i];
}
count--;
}
void solve()
{
init();
while (m--) {
int x, y;
scanf("%d%d", &x, &y);
x--;
y--;
unite(x, y);
}
printf("%d\n", count - 1);
}
int main()
{
//freopen("in.txt", "r", stdin);
for (;;) {
scanf("%d%d", &n, &m);
if (n == 0) break;
solve();
}
}
JAVA
import java.util.Scanner;
class UnionFind {
int n;
int[] par;
int[] rank;
UnionFind(int nn) {
n = nn;
par = new int[n];
rank = new int[n];
for (int i = 0; i < n; i++) {
par[i] = i;
rank[i] = i;
}
}
int find(int x) {
if (par[x] == x) {
return x;
}else
return par[x] = find(par[x]);
}
void unite(int x, int y) {
x = find(x);
y = find(y);
if (x == y) return;
if (rank[x] < rank[y]) {
par[x] = y;
} else {
par[y] = x;
if (rank[x] == rank[y]) rank[x]++;
}
}
boolean same(int x, int y) {
return find(x) == find(y);
}
void print() {
for (int i = 0; i < n; i++) {
System.out.print(" " + par[i]);
}
}
int total() {
int s = 0;
for (int i = 0; i < n; i++) {
if (par[i] == i) s++;
}
return s;
}
}
public class Main {
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
for (;;) {
int n = cin.nextInt();
if (n == 0) break;
int m = cin.nextInt();
UnionFind unionFind = new UnionFind(n);
for (int i = 0; i < m; i++) {
int u = cin.nextInt() - 1;
int v = cin.nextInt() - 1;
unionFind.unite(u, v);
}
System.out.println(unionFind.total() - 1);
}
}
}