Problem Description
Benny has a spacious farm land to irrigate. The farm land is a rectangle, and is divided into a lot of samll squares. Water pipes are placed in these squares. Different square has a different type of pipe. There are 11 types of pipes, which is marked from A to K, as Figure 1 shows.

Figure 1

Benny has a map of his farm, which is an array of marks denoting the distribution of water pipes over the whole farm. For example, if he has a map

ADC

FJK

IHE

then the water pipes are distributed like

Figure 2

Several wellsprings are found in the center of some squares, so water can flow along the pipes from one square to another. If water flow crosses one square, the whole farm land in this square is irrigated and will have a good harvest in autumn.

Now Benny wants to know at least how many wellsprings should be found to have the whole farm land irrigated. Can you help him?

Note: In the above example, at least 3 wellsprings are needed, as those red points in Figure 2 show.

 
Input
There are several test cases! In each test case, the first line contains 2 integers M and N, then M lines follow. In each of these lines, there are N characters, in the range of 'A' to 'K', denoting the type of water pipe over the corresponding square. A negative M or N denotes the end of input, else you can assume 1 <= M, N <= 50.

 
Output
For each test case, output in one line the least number of wellsprings needed.

 
Sample Input
2 2
DK
HF

3 3
ADC
FJK
IHE

-1 -1

 
Sample Output
2
3
 

解题思路:按行对每个节点map(i,j),找到其下方及右方的水管类型,判断其是否能与map(i,j)相连。在这题中只需要判断两个方向而不是四方方向。如下

1 2 3

4 5 6

从1判断2节点是否与1能够相连;若相连则把1和2放入到同一个集合类中,当下次从2搜索时,由于1和2已经在一个集合类中,所以不需要对1进行搜索;如果1和2无法连在一起,那么从2搜到1也是无法相连的。所以只需要搜索节点下方和右方的区域。

从上面给出的类型可以看出,遇到A,B,F,G这四种类型的水管时,不用搜索其下方的区域,因为无论其下方是什么类型都不可能与这四种水管相连。同样若是A,C,E,H这样的类型时也不需要考虑其右边的情况。

当前区域要想与下方的区域连在一起,则下方的水管类型只能下面的类型A,B,E,G,H,J,K。则样若与右方区域相连,右方区域的类型为A,C,F,G,H,I,K

#include<stdio.h>
#include<string.h>
//
char str[2][9]={{"ABEGHJK"},{"ACFGHIK"}};
int f[2505],m,n;
char map[52][52]; int check(int x,int y)
{
if(x>=0 && x<m && y>=0 && y<n)return 1;
return 0;
} int getFather(int a)
{
while(a!=f[a])a=f[a];
return a;
}
/** 合并两个集合 */
void Union(int a,int b)
{
int root1=getFather(a);
int root2=getFather(b);
if(root1!=root2)
{
if(root1<root2)f[root2]=root1;
else f[root1]=root2;
}
}
/**
* 判断两个型号的水管是否可以连在一起
*/
int judge(char c,int flag)
{
int i;
for(i=0;i<7;i++)
{
if(str[flag][i]==c)return i+1;
}
return 0;
}
void process()
{
int i,j,dx,dy;
char c;
for(i=0;i<=n*m;i++)f[i]=i;
for(i=0;i<m;i++)
{
for(j=0;j<n;j++)
{ c=map[i][j];
//判断下方,当前区域的类型是除A,B,F,G以外的。
if(c=='C' || c=='D' || c=='E' || c=='H'
|| c=='I' || c=='J' || c=='K')
{
dx = i+1;
dy = j;
if(check(dx,dy))
{
//下方区域是否是 A,B,E,G,H,J,K之一
if(judge(map[dx][dy],0))
{
//合并两个区域
Union(i*n+j,dx*n+dy);
}
}
}
//判断右方
if(c=='B' || c=='D' || c=='F' || c=='G'
|| c=='I' || c=='J' || c=='K')
{
dx=i;
dy=j+1;
if(check(dx,dy))
{
//右方区域是否是A,C,F,G,H,I,K之一
if(judge(map[dx][dy],1))
{
Union(i*n+j,dx*n+dy);
}
}
}
}
}
int result=0;
for(i=0;i<n*m;i++)if(f[i]==i)result++;
printf("%d\n",result);
}
int main()
{
int i;
while(scanf("%d%d",&m,&n))
{
if(m<0 || n<0)break;
for(i=0;i<m;i++)scanf("%s",map[i]);
process();
}
return 0;
}

hdu1198--并查集的更多相关文章

  1. hdu1198 Farm Irrigation —— dfs or 并查集

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1198 dfs: #include<cstdio>//hdu1198 dfs #includ ...

  2. HDU1198水管并查集Farm Irrigation

    Benny has a spacious farm land to irrigate. The farm land is a rectangle, and is divided into a lot ...

  3. hdu1198 Farm Irrigation 并查集

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1198 简单并查集 分别合并竖直方向和水平方向即可 代码: #include<iostream&g ...

  4. hdu1198 普通的并查集

    今天开始(第三轮)并查集,,之前学的忘了一些 本题很简单直接上代码 #include<iostream> #include<cstring> #include<cstdi ...

  5. hdu-1198 Farm Irrigation---并查集+模拟(附测试数据)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1198 题目大意: 有如上图11种土地块,块中的绿色线条为土地块中修好的水渠,现在一片土地由上述的各种 ...

  6. BZOJ 4199: [Noi2015]品酒大会 [后缀数组 带权并查集]

    4199: [Noi2015]品酒大会 UOJ:http://uoj.ac/problem/131 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品 ...

  7. 关押罪犯 and 食物链(并查集)

    题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用"怨气值"( ...

  8. 图的生成树(森林)(克鲁斯卡尔Kruskal算法和普里姆Prim算法)、以及并查集的使用

    图的连通性问题:无向图的连通分量和生成树,所有顶点均由边连接在一起,但不存在回路的图. 设图 G=(V, E) 是个连通图,当从图任一顶点出发遍历图G 时,将边集 E(G) 分成两个集合 T(G) 和 ...

  9. bzoj1854--并查集

    这题有一种神奇的并查集做法. 将每种属性作为一个点,每种装备作为一条边,则可以得到如下结论: 1.如果一个有n个点的连通块有n-1条边,则我们可以满足这个连通块的n-1个点. 2.如果一个有n个点的连 ...

  10. [bzoj3673][可持久化并查集 by zky] (rope(可持久化数组)+并查集=可持久化并查集)

    Description n个集合 m个操作 操作: 1 a b 合并a,b所在集合 2 k 回到第k次操作之后的状态(查询算作操作) 3 a b 询问a,b是否属于同一集合,是则输出1否则输出0 0& ...

随机推荐

  1. Linux进程和线程的比較

    进程与线程 參考:http://www.cnblogs.com/blueclue/archive/2010/07/16/1778855.html 首先比較Linux进程和线程的创建的差别,以此展开: ...

  2. JSP+Java+properties+FileInputStream文件读写,JSP页面读取properties文件

    String realPath = request.getRealPath("WEB-INF/classes/com/properties/devicetype.properties&quo ...

  3. Asp.net vNext 学习3

    Asp.net vNext 学习之路(三) asp.net vNext 对于构建asp.net 程序带来了一些重大的改变,让我们开发asp.net 程序的时候更加的方便和高效. 1,可以很容易的去管理 ...

  4. 【 c语言中无符号和有符号的加法运算】【深入理解】--【sky原创】

    原文:[ c语言中无符号和有符号的加法运算][深入理解]--[sky原创]   第一题 #include<stdio.h> int main() { unsigned int a=6; i ...

  5. C语言内存对齐(2)

    前两天参加了360测试实习生的笔试,碰到了一个有关c语言内存对齐的题目,回来后实现了一下,下面是代码: #include <stdio.h> #include <stdlib.h&g ...

  6. wsgi-restful-routes具体解释:

    感谢朋友支持本博客,欢迎共同探讨交流,因为能力和时间有限,错误之处在所难免,欢迎指正! 如有转载,请保留源作者博客信息. Better Me的博客:blog.csdn.net/tantexian 如需 ...

  7. mvc+EF比较好的框架

    个人看了传智播客的一位讲师搭建的框架感觉很好,就自己通过模仿划了一下很不讲究的类图来学习之间的关系(有些地方可能有自己理解不对的地方).很感激那位讲师,我会把这个框架用在我自己的项目中.

  8. boost------ref的使用(Boost程序库完全开发指南)读书笔记

    STL和Boost中的算法和函数大量使用了函数对象作为判断式或谓词参数,而这些参数都是传值语义,算法或函数在内部保修函数对象的拷贝并使用,例如: #include "stdafx.h&quo ...

  9. iOS基础 - XML & JSON

    一.HTML & XML HTML 是用来描述网页的一种语言 HTML 指的是超文本标记语言 (Hyper Text Markup Language) HTML 不是一种编程语言,而是一种标记 ...

  10. visual studio快捷键总结

    熟练操作vs的快捷键,可以有效地提高开发效率,下面将vs 2008与vs 2010的快捷键进行了总结,结果如下表: 注:vs 2010与vs 2008的快捷键基本相同. 编辑:   CTRL + M, ...