HDU 1198-Farm Irrigation

用到的算法:并查集

题意:

给你一块地,这块地被分割成许多小正方形,每个正方形中都安装了水管,不同的正方形中可能安装的水管不同,一共有11种水管,分别用字母A~K表示,某些正方形地块的中心有水源,问你至少需要多少个水管,以保证整个正方形农田都能被灌溉。

实际上这题就是求不通的集合有多少个

思路:将每个正方形土地上的水管按照顺时针方向标记,有水管记为1,没有记为0;

如果一个矩形的上面和下面是相互连通的或者左边和右边相互连通,那么,这两个就是属于同一个集合;

可以先假定所有的集合都是相互独立的,如果是属于相同的集合,那么总集合数减去1,最后剩下的就是真正不同的集合数了

#include<cstdio>
char mp[60][60];
int p[3600],sum,n,m;
int r[11][4]={{1,0,0,1},{1,1,0,0},{0,0,1,1},{0,1,1,0},{1,0,1,0},{0,1,0,1},
{1,1,0,1},{1,0,1,1},{0,1,1,1},{1,1,1,0},{1,1,1,1}};//按顺时针来标记每个水管的连通情况
int findx(int x)
{
	if(x!=p[x])
		p[x]=p[findx(p[x])];//一直向上寻找最初的节点
	return p[x];
}
int merge(int x,int y)//合并相同集合
{
	x=findx(x),y=findx(y);
	if(x==y)
		return 0; 
	p[x]=y;
	return 1;
	//上面的0和1表示这两个集合在合并之前属不属于同一个集合,0表示属于,1表示不属于
}
int main()
{
	while(scanf("%d %d",&n,&m),m>0||m>0)
	{
		sum=n*m;//假设每个集合都是各自独立的(都互不相通),即最多的集合数
		int i,j;
		for(i=0;i<sum;i++)
			p[i]=i;
		for(i=0;i<n;i++)
			scanf("%s",mp[i]);
		for(i=0;i<n;i++)
			for(j=0;j<m;j++)
			{
				//如过一个矩形的上面和另一个矩形的下面相连,那么这两个属于同一个集合
				if(i>0&&r[mp[i][j]-'A'][0]&&r[mp[i-1][j]-'A'][2])
					sum-=merge(i*m+j,(i-1)*m+j);//如果原先是不同的集合,现在合并成一个相同的集合,那么总集合数就就少掉1,即一个集合被另一个集和吞并了
				//同理左边和右边相连通,那么这两个也属于同一个集合
				if(j>0&&r[mp[i][j]-'A'][3]&&r[mp[i][j-1]-'A'][1])
					sum-=merge(i*m+j,i*m+j-1);
			}
			printf("%d\n",sum);
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值