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. 第3章1节《MonkeyRunner源码剖析》脚本编写示例: MonkeyRunner API使用示例(原创)

    天地会珠海分舵注:本来这一系列是准备出一本书的,详情请见早前博文“寻求合作伙伴编写<深入理解 MonkeyRunner>书籍“.但因为诸多原因,没有如愿.所以这里把草稿分享出来,所以错误在 ...

  2. 是男人就下100层【第四层】——Crazy贪吃蛇(1)

    贪吃蛇是一款非常经典的游戏,这些经典游戏给我们的童年添加了不少乐趣,今天開始我们来一步一步的在Android设备上实现一款贪吃蛇游戏,我也是第一次写这个游戏,有可能会写错,或者走弯路,可是终于希望能有 ...

  3. Nginx均衡负载(IP_HASH)未生效

    由于公司业务的发展,单台服务器已经无法满足并发和用户的需求,所以只能通过水平拓展的方式加机器来解决,线上采用的是Nginx+Tomcat集群的方式来解决.由于当前业务量不是很大,而且由于之前代码的问题 ...

  4. asterisk实时添加sip号码--sqlite篇

    原文:asterisk实时添加sip号码--sqlite篇 asterisk实时添加sip号码--sqlite篇 今天尝试用了asterisk的实时模式,往sqlite里面添加一个sip帐号,无需重启 ...

  5. leetcode第38题--Combination Sum

    题目: Given a set of candidate numbers (C) and a target number (T), find all unique combinations in C  ...

  6. JavaScript中对数组的操作

    原文:JavaScript中对数组的操作 一:数组的使用 1.定义:JavaScript中对数组的定义有两种形式.如: .var arr = [12,3,5,8]; .var arr = new Ar ...

  7. 解决IIS7 HTTP/405 Method Not Allowed 问题的方法.

    1.处理程序映射 2.添加脚本映射 3.请求路径:*.html 4.可执行文件:C:/windows/system32/inetsrv/asp.dll 5.请求限制-谓词:输入需要允许请求的谓词(po ...

  8. Smarty属性

    Attributes [属性] 大多数函数都带有自己的属性以便于明确说明或者修改他们的行为.  smarty函数的属性很像HTML中的属性.  静态数值不需要加引号,但是字符串建议使用引号.  如果用 ...

  9. Product Trader(操盘手)

    Product Trader(操盘手) 索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):Product Trader 的示例实现. 意图 使客户程序可以通过命名抽象超类和给定规 ...

  10. SZU:G32 Mass fraction

    Judge Info Memory Limit: 32768KB Case Time Limit: 5000MS Time Limit: 5000MS Judger: Float Numbers (1 ...