hdu1198--并查集

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.
DK
HF
3 3
ADC
FJK
IHE
-1 -1
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--并查集的更多相关文章
- hdu1198 Farm Irrigation —— dfs or 并查集
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1198 dfs: #include<cstdio>//hdu1198 dfs #includ ...
- HDU1198水管并查集Farm Irrigation
Benny has a spacious farm land to irrigate. The farm land is a rectangle, and is divided into a lot ...
- hdu1198 Farm Irrigation 并查集
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1198 简单并查集 分别合并竖直方向和水平方向即可 代码: #include<iostream&g ...
- hdu1198 普通的并查集
今天开始(第三轮)并查集,,之前学的忘了一些 本题很简单直接上代码 #include<iostream> #include<cstring> #include<cstdi ...
- hdu-1198 Farm Irrigation---并查集+模拟(附测试数据)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1198 题目大意: 有如上图11种土地块,块中的绿色线条为土地块中修好的水渠,现在一片土地由上述的各种 ...
- BZOJ 4199: [Noi2015]品酒大会 [后缀数组 带权并查集]
4199: [Noi2015]品酒大会 UOJ:http://uoj.ac/problem/131 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品 ...
- 关押罪犯 and 食物链(并查集)
题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用"怨气值"( ...
- 图的生成树(森林)(克鲁斯卡尔Kruskal算法和普里姆Prim算法)、以及并查集的使用
图的连通性问题:无向图的连通分量和生成树,所有顶点均由边连接在一起,但不存在回路的图. 设图 G=(V, E) 是个连通图,当从图任一顶点出发遍历图G 时,将边集 E(G) 分成两个集合 T(G) 和 ...
- bzoj1854--并查集
这题有一种神奇的并查集做法. 将每种属性作为一个点,每种装备作为一条边,则可以得到如下结论: 1.如果一个有n个点的连通块有n-1条边,则我们可以满足这个连通块的n-1个点. 2.如果一个有n个点的连 ...
- [bzoj3673][可持久化并查集 by zky] (rope(可持久化数组)+并查集=可持久化并查集)
Description n个集合 m个操作 操作: 1 a b 合并a,b所在集合 2 k 回到第k次操作之后的状态(查询算作操作) 3 a b 询问a,b是否属于同一集合,是则输出1否则输出0 0& ...
随机推荐
- 多线程学习之三生产者消费者模式Guarded Suspension
Guarded Suspension[生产消费者模式] 一:guarded suspension的参与者--->guardedObject(被防卫)参与者 1.1该 ...
- Windows下C语言的Socket编程例子(TCP和UDP)
原文:Windows下C语言的Socket编程例子(TCP和UDP) 刚刚学windows编程,所以想写学习笔记,这是一个简单的Socket程序例子,开发环境是vc6: 首先是TCP server端: ...
- Asp.Net MVC5入门学习系列③
原文:Asp.Net MVC5入门学习系列③ 添加一个视图(View) 接着上篇的入门系列,上面解说添加一个简单Controller(控制器),这里我们简单的在来添加一个View(视图)来展示我们Co ...
- java抽象类和接口的区别(转载)
1.Java接口和Java抽象类最大的一个区别,就在于Java抽象类可以提供某些方法的部分实现,而Java接口不可以,这大概就是Java抽象类唯一的优点吧,但这个优点非常有用. 如果向一个抽象类里加入 ...
- js面向对象+一般方法的选项卡
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- WebApiContrib
https://github.com/WebApiContrib ASP.NET Web API and Protocol Buffers Protocol Buffers are a super e ...
- windows下使用pthread
有的时候需要使用多线程来测试代码啥的,在Linux下有pthread,在windows也有. 我这儿是使用MingW作为编译工具,具体如何下载MingW自行在网上搜索. 而pthread是在这里下载的 ...
- SSRS (SQL Server Report Service) 在IE9, IE10下显示不全的解决办法
原文:SSRS (SQL Server Report Service) 在IE9, IE10下显示不全的解决办法 在做项目的过程中遇到SSRS与IE9, IE10不兼容的情况,具体表现为报表页面在IE ...
- 读书笔记—CLR via C#线程25-26章节
前言 这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可 ...
- mysql通过字段注释查找字段名称
原文:mysql通过字段注释查找字段名称 有时候表的字段太多,只是大致记得表的注释,想通过字段注释查找字段名称,可以用如下语句: SELECT COLUMN_NAME,column_comment F ...