题目链接:hdu 1198
题意:给出一张水管图, 有水管相连的水可以通往各处,问你至少需要多少个水源,让所有水管通水。显然用并查集,判断到最后有多少个集合。
代码:
#include<cstdio>
#include<iostream>
using namespace std;
#define maxn 100
struct Pipe{
int down, left, right, up;
}pp[15];
char str[maxn][maxn];
int cnt;
int hhash[maxn * maxn];
int p[maxn * maxn];
int find(int x)
{
if(p[x] == -1) return x;
return p[x] = find(p[x]);
}
void bing(int x, int y)
{
int p1 = find(x);
int p2 = find(y);
if(p1 != p2) p[p1] = p2;
}
int main()
{
int n, m;
pp[1].up = 1; pp[1].right = 0; pp[1].down = 0; pp[1].left = 1;
pp[2].up = 1; pp[2].right = 1; pp[2].down = 0; pp[2].left = 0;
pp[3].up = 0; pp[3].right = 0; pp[3].down = 1; pp[3].left = 1;
pp[4].up = 0; pp[4].right = 1; pp[4].down = 1; pp[4].left = 0;
pp[5].up = 1; pp[5].right = 0; pp[5].down = 1; pp[5].left = 0;
pp[6].up = 0; pp[6].right = 1; pp[6].down = 0; pp[6].left = 1;
pp[7].up = 1; pp[7].right = 1; pp[7].down = 0; pp[7].left = 1;
pp[8].up = 1; pp[8].right = 0; pp[8].down = 1; pp[8].left = 1;
pp[9].up = 0; pp[9].right = 1; pp[9].down = 1; pp[9].left = 1;
pp[10].up = 1; pp[10].right = 1; pp[10].down = 1; pp[10].left = 0;
pp[11].up = 1; pp[11].right = 1; pp[11].down = 1; pp[11].left = 1;
while(~scanf("%d%d", &n, &m)){
if(n < 0 && m < 0) break;
int res = 0;
cnt = 0;
for(int i = 1; i < maxn*maxn; i++){
p[i] = -1;
hhash[i] = -1;
}
for(int i = 0; i < n; i++){
cin >> str[i];
}
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++){
cnt++;
int index = str[i][j] - 'A' + 1;
if(j != 0){
int index_pre = str[i][j - 1] - 'A' + 1;
if(pp[index_pre].right && pp[index].left){
bing(cnt, cnt - 1);
}
}
if(i != 0){
int index_pre = str[i - 1][j] - 'A' + 1;
if(pp[index_pre].down && pp[index].up){
bing(cnt, cnt - m);
}
}
}
for(int i = 1; i <= cnt; i++){
int num = find(i);
if(hhash[num] == -1){
res++;
hhash[num] = 1;
}
}
printf("%d\n", res);
}
return 0;
}