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. IOS开发之——使用SBJson拼接Json字符串

    SBJson包的下载地址在上一篇文章中. 能够使用NSDictionary中的键值对来拼接Json数据,很方便,也能够进行嵌套,直接上代码: //開始拼接Json字符串 NSDictionary *d ...

  2. Ubuntu Ruby On Rails安装和配置

    在这篇文章中ubuntu通过rvm安装ruby和rails.步借鉴了官方网站和网上信息,这里给大家分享. 1. 安装mapapis公钥: gpg --keyserver hkp://keys.gnup ...

  3. python基础课程_学习笔记20:标准库:有些收藏夹——os

    标准库:有些收藏夹 os os模块为您提供访问多个操作系统服务特征. os和它的子模块os.path还包含一些用于检查.构造.删除文件夹和文件的函数,以及一些处理路径的函数. os模块中一些重要函数和 ...

  4. 必须掌握的JavaScript基本知识

    作为一个前端工作者,应该了解一些javascript的发展历史,javascript实现及版本等.基本概念包括语法.关键字.变量.数据类型.操作符.语句控制及函数等,它们和我们学习的其它语言C/C++ ...

  5. C#压缩字符串

    在论坛上看到一个压缩字符串的问题,特此记录以备后用! static string GetStringR(string inputStr) { return Regex.Replace(inputStr ...

  6. div高度自适外层div高度随里层div高度自适

    尝试过许多办法 其中一网友的最靠谱就是在外层div样式添加两个标签(不能少) clear:both;  overflow:auto;

  7. .NET MVC学习之模型绑定

    ASP.NET MVC学习之模型绑定(2)   继ASP.NET MVC学习之模型绑定继续 3.手工调用模型绑定 很多情况下我们都是通过形参的方式接收来自http流中的数据,这看似是完美的,但是缺少了 ...

  8. Oracle单行函数笔记

    Oracle中单行函数的分类:1.字符函数substr():字符串截取select substr('我爱你,你知道么?',0,4) from dual执行结果:我爱你,length函数:字符串长度se ...

  9. iOS基础 - CALayer

    一.CALayer简介 Core Animation是跨平台的,支持iOS环境和Mac OS X环境 凡是支持跨平台的框架,都不能直接使用UIKit框架,因为UIKit框架只能应用在iOS而不能用于M ...

  10. [转]Libev源码分析 -- 整体设计

    Libev源码分析 -- 整体设计 libev是Marc Lehmann用C写的高性能事件循环库.通过libev,可以灵活地把各种事件组织管理起来,如:时钟.io.信号等.libev在业界内也是广受好 ...