您的位置:首页 > 其它

hdu 1198 Farm Irrigation(并查集)

2014-08-25 20:35 405 查看
http://acm.hdu.edu.cn/showproblem.php?pid=1198

题目大意:Benny将农场分割成一些小矩形,每个矩形都放一种形状的水管,问需要多少水源能浇灌整个农场。

                    将每种形状的水管四个方向标记,能流通为1,不嗯能够流通为0。

                    之后就可以讲流通的水管并起来。

代码如下:

#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;
int set[3000],map[][4]={1,1,0,0,0,1,1,0,1,0,0,1,0,0,1,1,0,1,0,1,1,0,1,0,1,1,1,0,1,1,0,1,1,0,1,1,0,1,1,1,1,1,1,1};//从A到K顺序保存四个方向
int find(int a)//找根节点
{
while(a!=set[a])
a=set[a];
return a;
}
void Union(int a,int b)//合并
{
a=find(a);
b=find(b);
set[a]=b;
}
bool zuoyou(int a,int b)//判断能否流通
{
if(map[a][2]==1&&map[b][0]==1)
return 1;
return 0;
}
bool shangxia(int a,int b)//判断能否流通
{
if(map[a][3]==1&&map[b][1]==1)
return 1;
return 0;
}
int main()
{
int m,n,i,j,sum;
char type[51][51];
while(~scanf("%d%d%*c",&m,&n))
{
if(m==-1&&n==-1)
break;
for(i=1;i<=m*n;i++)
set[i]=i;
for(i=1;i<=m;i++)
{
for(j=1;j<=n;j++)
{
scanf("%c",&type[i][j]);
if(i==1)
{
//以左上角为起点向右下角合并
if(j!=1)
{
if(zuoyou(type[i][j-1]-'A',type[i][j]-'A')==1)//第一行的都只向左并
Union((i-1)*n+j,(i-1)*n+j-1);
}
}
else
{
if(j==1)
{
if(shangxia(type[i-1][j]-'A',type[i][j]-'A')==1)//第一列只向上并
Union((i-2)*n+j,(i-1)*n+j);
}
else
{
//中间的都向左上并
if(zuoyou(type[i][j-1]-'A',type[i][j]-'A')==1)
Union((i-1)*n+j,(i-1)*n+j-1);
if(shangxia(type[i-1][j]-'A',type[i][j]-'A')==1)
Union((i-2)*n+j,(i-1)*n+j);
}
}
}
scanf("%*c");
}
sum=0;
for(i=1;i<=m*n;i++)//查找根节点数
if(set[i]==i)
sum++;
printf("%d\n",sum);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: