题目链接: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; }