zoukankan      html  css  js  c++  java
  • 利用DFS算出有多少个连通图

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

        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);
                }
            }
        }
    
    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数组变一变即可。
    注意:四连通图也是八联通图,也就是说一个格的也行。

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

    #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
    ", cnt);
    }
    
    
  • 相关阅读:
    Mac idea 打不开
    git学习之git reset命令
    更改 macOS 用户帐户和个人文件夹的名称
    SpringBoot系列: 如何优雅停止服务
    windows环境下启动mongodb服务
    rocketMq4.2.0启动broker报错找不到或无法加载主类 FilesJavajdk1.8.0_101libdt.jar;C:Program]
    初创公司与成熟的公司各有什么利弊?有5年工作经验的人适合进那一个?(行业职位是一样的情况下)
    mac 10.15 国内如何安装brew
    Mac下SSH Key配置
    买苹果MacBook Pro ,有必要买care吗?
  • 原文地址:https://www.cnblogs.com/KeepZ/p/12128432.html
Copyright © 2011-2022 走看看