首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> 關於C

C 語言 BFS 最短路徑實戰:雙源點會合 KFC(HDU 1010 / 多源 BFS)

     編輯:關於C

問題描述

地圖 n×m (≤200),Y、M 為兩人起點,@ 為 KFC,# 障礙,. 道路。雙方同速(每步 11 分鐘),找一個 KFC 使雙方步數之和最小,輸出總時間。

算法:雙 BFS + 彙總

  1. 以 Y 為起點 BFS,記錄每個 @ 的距離 distY
  2. 以 M 為起點 BFS,記錄每個 @ 的距離 distM
  3. 遍歷所有 @,取 min(distY + distM) × 11

時間複雜度 O(n×m),空間 O(n×m)。

完整代碼

#include 
#include 
#include 

#define MAXN 210
#define INF  0x3f3f3f3f

char map[MAXN][MAXN];
int distY[MAXN][MAXN], distM[MAXN][MAXN];
int n, m;

struct Node { int x, y, d; } q[MAXN*MAXN];
int dx[4] = {1,-1,0,0}, dy[4] = {0,0,1,-1};

void bfs(int sx, int sy, int dist[][MAXN]) {
    int head = 0, tail = 0;
    q[tail++] = (struct Node){sx, sy, 0};
    dist[sx][sy] = 0;

    while (head < tail) {
        struct Node cur = q[head++];
        for (int i = 0; i < 4; i++) {
            int nx = cur.x + dx[i], ny = cur.y + dy[i];
            if (nx<0 || nx>=n || ny<0 || ny>=m) continue;
            if (map[nx][ny] == '#') continue;
            if (dist[nx][ny] != INF) continue;
            dist[nx][ny] = cur.d + 1;
            q[tail++] = (struct Node){nx, ny, cur.d + 1};
        }
    }
}

int main() {
    while (scanf("%d %d", &n, &m) == 2) {
        int yx=-1, yy=-1, mx=-1, my=-1;
        for (int i = 0; i < n; i++) {
            scanf("%s", map[i]);
            for (int j = 0; j < m; j++) {
                if (map[i][j] == 'Y') { yx=i; yy=j; }
                if (map[i][j] == 'M') { mx=i; my=j; }
            }
        }

        memset(distY, 0x3f, sizeof(distY));
        memset(distM, 0x3f, sizeof(distM));
        bfs(yx, yy, distY);
        bfs(mx, my, distM);

        int ans = INF;
        for (int i = 0; i < n; i++)
            for (int j = 0; j < m; j++)
                if (map[i][j] == '@' && distY[i][j]!=INF && distM[i][j]!=INF)
                    ans = ans < distY[i][j]+distM[i][j] ? ans : distY[i][j]+distM[i][j];

        printf("%d\n", ans * 11);
    }
    return 0;
}

樣例驗證

Input:
4 4
Y.#@
....
.#..
@..M
4 4
Y.#@
....
.#..
@#.M
5 5
Y..@.
.#...
.#...
@..M.
#...#

Output:
66
88
66

關鍵技術點

技術說明
靜態隊列避免 malloc 開銷,MAXN*MAXN 足夠
0x3f 初始化memset(dist, 0x3f, ...) 快速置 INF (≈1e9)
雙 BFS 獨立互不干擾,最後彙總
步數轉時間題目每步 11 分鐘,最終乘 11

擴展:單 BFS 多源點

若只需「任意一人到最近 KFC」,可將 Y、M 同時入隊初始化 dist=0,一次 BFS 完成。

總結

雙 BFS 解決雙源點會合最短路徑是圖論基礎模板。關鍵在於分別計算單源最短路、彙總取最小,代碼簡潔、複雜度最優,廣泛適用於網格地圖、迷宮、多人會合等場景。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved