前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >利用DFS算出有多少个连通图

利用DFS算出有多少个连通图

作者头像
_DIY
发布2020-02-11 18:37:58
8410
发布2020-02-11 18:37:58
举报

以下面一个题目为例,[题目链接]: https://www.luogu.com.cn/problem/P4961 题目中涉及求出八联通图的个数,这里给出这步的代码:

代码语言:javascript
复制
    memset(vis, 0, sizeof(vis));
    int cnt = 0;
    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < m; j++)
        {
            if(!bomb[i][j] && !vis[i][j])
            {
                ++cnt;
                vis[i][j] = 1;
                dfs(i, j);
            }
        }
    }
代码语言:javascript
复制
void dfs(int x, int y)
{
    for(int i = 0; i < 8; i++)
    {
        int xx = x + dx[i];
        int yy = y + dy[i];
        if(xx >= 0 && xx < n && yy >= 0 && yy < m && !vis[xx][yy] && !bomb[xx][yy])
        {
            vis[xx][yy] = 1;
            dfs(xx, yy);
        }
    }
}

上面介绍的是求八连通图的个数,类似,求四联通图的个数也是相似的做法,只需把dx,dy数组变一变即可。 注意:四连通图也是八联通图,也就是说一个格的也行。

下面给出关于那道题目的代码:

代码语言:javascript
复制
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 2000;
int n, m;
int dx[] = {0, 0, -1, -1, -1, 1, 1, 1};
int dy[] = {1, -1, 0, 1, -1, 0, 1, -1};
int bomb[maxn][maxn], vis[maxn][maxn];
void dfs(int x, int y)
{
    for(int i = 0; i < 8; i++)
    {
        int xx = x + dx[i];
        int yy = y + dy[i];
        if(xx >= 0 && xx < n && yy >= 0 && yy < m && !vis[xx][yy] && !bomb[xx][yy])
        {
            vis[xx][yy] = 1;
            dfs(xx, yy);
        }
    }
}
int main()
{
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    scanf("%d %d", &n, &m);
    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < m; j++)
        {
            scanf("%d", &bomb[i][j]);
            if(bomb[i][j])
                bomb[i][j] = -1;
        }
    }
    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < m; j ++)
        {
            if(bomb[i][j] == -1)
                continue;
            for(int ans = 0; ans < 8; ans++)
            {
                int xx = dx[ans] + i;
                int yy = dy[ans] + j;
                if(xx >= 0 && xx < n && yy >= 0 && yy < m && bomb[xx][yy] == -1)
                    ++bomb[i][j];
            }
        }
    }
    memset(vis, 0, sizeof(vis));
    int cnt = 0;
    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < m; j++)
        {
            if(!bomb[i][j] && !vis[i][j])
            {
                ++cnt;
                vis[i][j] = 1;
                dfs(i, j);
            }
        }
    }
    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < m; j++)
        {
            if(bomb[i][j] != 0 && bomb[i][j] != -1)
            {
                int flag = 0;
                for(int k = 0; k < 8; k++)
                {
                    int xx = i + dx[k];
                    int yy = j + dy[k];
                    if(xx < 0 || xx >= n || yy < 0 || yy >= m)
                        continue;
                    if(xx >= 0 && xx < n && yy >= 0 && yy < m && bomb[xx][yy] == 0)
                    {
                        flag = 1;
                        break;
                    }
                }
                if(!flag)
                    ++cnt;
            }
        }
    }

    printf("%d\n", cnt);
}
本文参与?腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-01-01 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客?前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com