30分求调www
查看原帖
30分求调www
902613
purple_blue楼主2025/8/31 14:13
//堆优化的dijkstra
#include <iostream>
#include <vector>
#include <queue>
#include <cstring>
#include <algorithm>

using namespace std;

// 节点结构体,用于优先队列
struct Node {
    int r, c, dist;
    bool operator > (const Node& b) const {
        return dist > b.dist;
    }
};

const int N = 1010;
const int INF = 0x3f3f3f3f;

int n, m;
int Ra, Rb, Rc;
int grid[N][N];
int distA[N][N];
int distB[N][N];
int distO[N][N];
bool st[N][N];

// 方向数组:上、下、左、右
int dr[] = {-1, 1, 0, 0};
int dc[] = {0, 0, -1, 1};

// 堆优化的 Dijkstra 函数
void dijkstra(int x, int y, int dist[N][N]) {
    // 初始化距离数组和访问状态
    memset(dist, 0x3f, sizeof(distA));
    memset(st, false, sizeof(st));

    priority_queue<Node, vector<Node>, greater<Node>> heap;

    // 起点初始化
    dist[x][y] = grid[x][y];
    heap.push({x, y, dist[x][y]});

    while (!heap.empty()) {
        Node cur = heap.top();
        heap.pop();

        int r = cur.r;
        int c = cur.c;

        if (st[r][c]) {
            continue;
        }
        st[r][c] = true;

        // 遍历所有相邻节点
        for (int i = 0; i < 4; ++i) {
            int r1 = r + dr[i];
            int c1 = c + dc[i];

            // 检查边界
            if (r1 >= 1 && r1 <= n && c1 >= 1 && c1 <= m) {
                // 计算新路径的距离
                int new_dist = dist[r][c] + grid[r1][c1];

                // 更新距离
                if (dist[r1][c1] > new_dist) {
                    dist[r1][c1] = new_dist;
                    heap.push({r1, c1, new_dist});
                }
            }
        }
    }
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int a, b, c;
    cin >> n >> m >> a >> b >> c;

    int x_O = 1, y_O = a;
    int x_A = n, y_A = b;
    int x_B = n, y_B = c;

    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            cin >> grid[i][j];
        }
    }

    // 三次 Dijkstra 算法
    dijkstra(x_A, y_A, distA);
    dijkstra(x_B, y_B, distB);
    dijkstra(x_O, y_O, distO);

    // 遍历所有可能的交汇点,找到最小总电阻
    long long res = INF;
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            long long l = (long long)distA[i][j] + distB[i][j] + distO[i][j] - 2 * grid[i][j];
            if (res > l) {
                res = l;
            }
        }
    }

    cout << res << endl;

    return 0;
}
2025/8/31 14:13
加载中...