【HDU】1198 Farm Irrigation (二维并差集查找联通块数量)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1198

题目:图源自HDU题目

给出11个图,然后输入其中的字母组成n*m的一个图,问这个图中的联通块的数目

思路:

从上到下,从左到右一次遍历每一个格子。如果当前格子的上(下左右)方还有另一个格子且它们在交界处相连,那么就合并这两个格子所属的连通分量。

其实觉得比较麻烦的一点是每一个小图(A~K)的数据组成上传,其余的直接看代码吧

 

代码:

#include<cstring>
#include<cstdio>
#include<algorithm>
#define maxn 110
using namespace std;

pair<int,int > fa[maxn][maxn];
pair<int,int > findest(int x,int y)
{
    return fa[x][y]==make_pair(-1,-1)? make_pair(x,y):fa[x][y]=findest(fa[x][y].first,fa[x][y].second);
}

int bind(int x1,int y1,int x2,int y2)
{
    pair<int,int > p1=findest(x1,y1);
    pair<int,int > p2=findest(x2,y2);
    if(p1!=p2)
    {
        fa[p1.first][p1.second]=p2;
        return 1;
    }
    return 0;
}

int pipe[4][11]=
{
    {1,1,0,0,1,0,1,1,0,1,1},
    {0,0,1,1,1,0,0,1,1,1,1},
    {1,0,1,0,0,1,1,1,1,0,1},
    {0,1,0,1,0,1,1,0,1,1,1}
};
int dx[]= {-1,1,0,0};
int dy[]= {0,0,-1,1};
int re_dir[]= {1,0,3,2};

int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m)==2 && n>=1 && m>=1)
    {
        for(int i=0; i<n; i++)
            for(int j=0; j<m; j++)
                fa[i][j]=make_pair(-1,-1);

        int mp[maxn][maxn];

        for(int i=0; i<n; i++)
            for(int j=0; j<m; j++)
            {
                char c;
                scanf(" %c",&c);
                mp[i][j]=c-'A';
            }


        int cnt=n*m;
        for(int x=0; x<n; x++)
        {
            for(int y=0; y<m; y++)
            {
                if(x==1&&y==1)
                {
                    int g=0;
                }
                for(int dir=0; dir<4; dir++)
                {
                    int nx=x+dx[dir];
                    int ny=y+dy[dir];
                    if(nx>=0&&nx<n&&ny>=0&&ny<m)
                    {
                        if(pipe[dir][mp[x][y]] && pipe[re_dir[dir]][mp[nx][ny]])
                            cnt -= bind(x,y,nx,ny);
                    }
                }
            }
        }
        printf("%d\n",cnt);
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值