首页 > 其他分享 >【搜索】多源BFS专题

【搜索】多源BFS专题

时间:2025-01-16 20:11:08浏览次数:1  
标签:专题 dist int res BFS ++ step total 多源

跳马(多源BFS变种,每个起点有步数限制)

image

image

补充几个测试样例
输入

3 2
. .
2 .
. .

输出

0

输入

3 5
4 7 . 4 8
4 7 4 4 .
7 . . . .

输出

17

输入

3 4
. . . .
. 2 . .
. . . .

输出

0

输入

3 4
. . . .
. 2 2 .
. . . .

输出

-1

本题很坑爹的地方在于,输入的字符串还用空格分开,所以读入时不能用读连续字符串的方法,例如
读字符串数组(n * m字符矩阵,中间无空格)char g[N][N]写法

for (int i = 0; i < n; i++) scanf("%s", g[i]);//读取
for (int i = 0; i < n; i++) printf("%s\n", g[i]);//输出写法1
for (int i = 0; i < n; i++) puts(g[i]);//输出写法2

只能当成矩阵一个一个读,就和读int型二维矩阵一样。

分析:本题数据量不大且因为每个点有移动步数限制,所以采用每个点都搜一次的方法,搜完一个点,dist数组中存的就是该点到其余所有位置的最小步数,更新到total数组中,如果dist[i][j] == -1,或dist[i][j] > step,则说明该点不可达,在total中标记为-1.
最后遍历一遍total数组,把所有-1改成正无穷,再取最小值输出即可。

C++代码

/**
 * Created by Tshaxz on 25-1-16.
 */
#include <iostream>
#include <cstring>
#include <queue>

using namespace std;

typedef pair<int, int> PII;

const int N = 30, INF = 0x3f3f3f3f;

int n, m;
char g[N][N];
int dist[N][N], total[N][N];
int dx[8] = {1, 2, 2, 1, -1, -2, -2, -1};
int dy[8] = {2, 1, -1, -2, -2, -1, 1, 2};

void bfs(int x, int y, int step)
{
    memset(dist, -1, sizeof dist);
    queue<PII> q;
    dist[x][y] = 0;
    q.push({x, y});

    while (q.size())
    {
        auto [x, y] = q.front();
        q.pop();

        for (int i = 0; i < 8; i++)
        {
            int a = x + dx[i], b = y + dy[i];
            if (a < 0 || a >= n || b < 0 || b >= m) continue;
            if (dist[a][b] != -1) continue;
            if (dist[a][b] > step) continue;
            dist[a][b] = dist[x][y] + 1;
            q.push({a, b});
        }

    }
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);

    cin >> n >> m;
    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++)
            cin >> g[i][j];

    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++)
            if (g[i][j] != '.')
            {
                int step = g[i][j] - '0';
                bfs(i, j, step);
                for (int x = 0; x < n; x++)
                    for (int y = 0; y < m; y++)
                    {
                        if (dist[x][y] > step) total[x][y] = -1;
                        else if (total[x][y] != -1) total[x][y] += dist[x][y];
                    }
            }


    int res = INF;
    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++)
        {
            if (total[i][j] == -1) total[i][j] = INF;
            res = min(res, total[i][j]);
        }

    if (res == INF) res = -1;
    cout << res << '\n';
    return 0;
}

debug版代码,可以输出dist与total数组查看

/**
 * Created by Tshaxz on 25-1-16.
 */
#include <iostream>
#include <cstring>
#include <queue>

using namespace std;

typedef pair<int, int> PII;

const int N = 30, INF = 0x3f3f3f3f;

int n, m;
char g[N][N];
int dist[N][N], total[N][N];
int dx[8] = {1, 2, 2, 1, -1, -2, -2, -1};
int dy[8] = {2, 1, -1, -2, -2, -1, 1, 2};

void bfs(int x, int y, int step)
{
    memset(dist, -1, sizeof dist);
    queue<PII> q;
    dist[x][y] = 0;
    q.push({x, y});

    // printf("step: %d\n", step);
    while (q.size())
    {
        auto [x, y] = q.front();
        q.pop();

        for (int i = 0; i < 8; i++)
        {
            int a = x + dx[i], b = y + dy[i];
            if (a < 0 || a >= n || b < 0 || b >= m) continue;
            if (dist[a][b] != -1) continue;
            if (dist[a][b] > step) continue;
            dist[a][b] = dist[x][y] + 1;
            q.push({a, b});
        }

    }
}

// void print1()
// {
//     printf("dist: \n");
//     for (int i = 0; i < n; i++)
//     {
//         for (int j = 0; j < m; j++) printf("\t%d\t", dist[i][j]);
//         puts("");
//     }
// }

// void print2()
// {
//     printf("total:\n");
//     for (int i = 0; i < n; i++)
//     {
//         for (int j = 0; j < m; j++) printf("\t%d\t", total[i][j]);
//         puts("");
//     }
// }

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);

    cin >> n >> m;
    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++)
            cin >> g[i][j];

    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++)
            if (g[i][j] != '.')
            {
                int step = g[i][j] - '0';
                bfs(i, j, step);
                // printf("当前的马:g[%d][%d]:%c\n", i, j, g[i][j]);
                // print1();
                for (int x = 0; x < n; x++)
                    for (int y = 0; y < m; y++)
                    {
                        if (dist[x][y] > step) total[x][y] = -1;
                        else if (total[x][y] != -1) total[x][y] += dist[x][y];
                    }
                
                // print2();
            }
            
            
    int res = INF;
    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++)
        {
            if (total[i][j] == -1) total[i][j] = INF;
            res = min(res, total[i][j]);
        }
            
    if (res == INF) res = -1;
    cout << res << '\n';
    return 0;
}

标签:专题,dist,int,res,BFS,++,step,total,多源
From: https://www.cnblogs.com/Tshaxz/p/18675683

相关文章

  • BFS 2025/1/16
    BFSBasic主要特点:空间复杂度较高,基于队列经常用于求最优解的搜索题经典模型:连通块,最短迷宫路径,曼哈顿距离Question01[ACP2056山峰与山谷]主体是广搜模板难点在于如何判断当前联通块是山峰或山谷考虑在广搜时进行维护如果BFS检测到的区域不是在当前连通......
  • 华为ACL 场景问题专题- ACL 不足和 ACL 不生效
    互联网各领域资料分享专区(不定期更新):SheetACL使用不足ACL使用不足表现为下发MQC配置时报错资源不足,首先介绍下资源情况:12800/6870资源情况:ACL资源种类包含TCAM、KB、CE等,有任何一种资源不够,ACL业务就会下发失败。TCAM:TCAM用于存放用户下发的各个ACL......
  • 【2024遥感应用组一等奖】基于ENVI Deep Learning的多源SAR影像海带水淹区域提取与分
    作品介绍01应用背景近年来,随着全球气候变化的加剧,海岸带地区面临的洪水威胁日益严重。这些极端天气事件,特别是由热带气旋引发的洪水,不仅给沿海地区带来了巨大的经济损失,还对当地居民的安全和生活产生了深远影响。因此,能够准确识别海岸地区的水淹区域对于防灾减灾、制定应对策......
  • 【专题】2024年抖音电商年度高增长报告汇总PDF洞察(附原数据表)
    原文链接:https://tecdat.cn/?p=387972024年,服装内衣和美妆护肤品类在抖音电商平台上成为增长的强劲动力。相关统计显示,服装内衣品类的年增长率达到了29.59%。其中,少女文胸、唐装、民族服装和舞台服装的增长尤为显著,分别实现了59.17%和374.15%的增幅。消费者对内衣的舒适性和功能......
  • 【专题】2025年节日营销趋势洞察报告汇总PDF洞察(附原数据表)
    原文链接: https://tecdat.cn/?p=38813在当今复杂多变且竞争激烈的消费市场环境下,节日营销已成为企业获取市场份额、提升品牌影响力的关键战略时机。我们深知深入洞察节日营销趋势对于企业决策的重要性。本报告汇总基于对2024年多个关键消费节点及消费者行为的深度调研,涵盖61......
  • 排序算法专题总结
    分治基础-二分查找:二分查找是一种高效的查找算法先找到数组的中间位置mid,判断(1)如果要找的数x==a[mid]找到了,mid就是位置(2)如果要找的教x>a[mid],说明要找的数在后一半,递归在后一半找(3)如果要找的数x<a[mid],说明要找的数在前一半,递归在前一半找在下标为left~right之间的......
  • 省选构造专题
    省选构造专题Thesamepermutation首先打个表,发现在\(1\len\le5\)之内的是否有合法方案的情况为√××√√大了打不出来了。考虑一下\(4,5\)连续有解,注意到一个偶数有解,则这个偶数\(+1\)也必定有解。考虑以下构造方法即对于某一个交换,可以在它前后各添加一个右端......
  • 【电源专题】开关波形测试为什么需要探头尖端适配器,没有的话怎么低成本改造一个?
        在文章【电源专题】为什么测试电源的SW波形上冲振荡之前的0V电位要先来个小的下降-CSDN博客中我们提到了开关波形的形成,那么开关波形的测试过程中我们需要注意什么呢?        对于开关电源和电机驱动电路等,在测量功率元件管脚来观测开关位置波形的时候,因为......
  • 【专题】2024年电商报告汇总PDF洞察(附原数据表)
    原文链接: https://tecdat.cn/?p=38770在当今数字化浪潮汹涌澎湃的时代背景下,电商行业已然成为全球经济格局中极具影响力与活力的关键领域。从中国电商市场的增长压力与结构变化,到各类促销活动背后的消费者行为逻辑;从不同平台内容创作者生态的差异化表现,再到跨境出海、AI技术应......
  • 第三届智能决策论坛|决策大模型专题报告——随笔(1)
    前言这次汇报的有四位老师,其中我比较感兴趣的是上海交通大学张伟楠老师、北京大学梁一韬老师和清华大学高宸老师的报告,其中张老师之前已经记录过,本文主要作为对梁一韬老师的分享的记录与思考。CRAFTJARVIS:TowardsGeneralistAgentsinanOpenWorldMotivation研究趋势:构......