HDU1198Farm Irrigation——并查集

来源:互联网 发布:淘宝中国知网账号 编辑:程序博客网 时间:2024/05/22 05:01

题意:就是找在整个地图中有多少个连通的水管;

思路:先判断是否连通,然后再判断是否需要连接;

因为只是判断相邻片段的水管是否连通,所以在存放的时候用0和1来代表

总结:这道题有一个小细节,就是如果用并查集存的话,需要注意,一个片段是可以重复使用的,所以如果用编号存根节点的话一定是不对的,所以要用片段在地图上的位置来判断根节点。

还有就是一般情况下,数组的开头都用1,把零空出来,会好理解一些。

代码::

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<math.h>
using namespace std;
int map[12][4]=
{
0,0,0,0,
    1,1,0,0,
    1,0,1,0,
    0,1,0,1,
    0,0,1,1,
    1,0,0,1,
    0,1,1,0,
    1,1,1,0,
    1,1,0,1,
    0,1,1,1,
    1,0,1,1,
    1,1,1,1};//存放片段的水管情况,1代表有,0代表没有 
int dir[4][2]={-1,0,0,-1,0,1,1,0};//上0左1右2下3
char aa[55][55];
int bb[55][55];
int root[55*55];
int next_x,next_y;
int n,m;
int find_root(int son)
{
if(son!=root[son])
{
root[son]=find_root(root[son]);
}
return root[son];
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
if(n<0||m<0) break;
for(int i=1;i<=n;i++)
{
getchar();  //别忘记吸收多余的字符 
for(int j=1;j<=m;j++)
{
scanf("%c",&aa[i][j]);
bb[i][j]=aa[i][j]-'A'+1;//代表map中的横坐标 
}
}
for(int i=1;i<=n*m;i++)//初始化 
{
root[i]=i;
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
for(int k=0;k<4;k++)
{
next_x=i+dir[k][0];
next_y=j+dir[k][1];
if(next_x>0&&next_y>0&&next_x<=n&&next_y<=m)//没出界 
{
if(map[bb[i][j]][k]==1&&map[bb[next_x][next_y]][3-k]==1)//连通的 用3减,关系:上+下=3,左+右=3 
{
int fx,fy;
fx=find_root((i-1)*m+j);//记得寻找根节点一定要用地图中的位置,还要减1,不解释为啥 
fy=find_root((next_x-1)*m+next_y);
if(fx!=fy)
{
root[fy]=fx;
}
}
}
}
}
}
int num=0;
for(int i=1;i<=n*m;i++)
{
if(root[i]==i)
{
num++;
}
}
printf("%d\n",num);
}
return 0;
}

0 0
原创粉丝点击