Poj1502.MPI Maelstrom(Dijkstra&Bellman-Ford)

题目链接:http://poj.org/problem?id=1502
思路:这道题本质是求单源最短路径。Dijkstra算法解决,利用dist数组保存每个顶点到源点的最短路径,利用visited数组标示该顶点是否被访问,每一次更新dist时顺便找出未被访问点到源点的最短路径。代码实现如下:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

const int MAXN = 105;
const int INF = 0xfffffff;
int n, graph[MAXN][MAXN], dist[MAXN], visited[MAXN];


int str_to_price(char *str) {
    int price = 0;

    if (str[0] != 'x') {
        for (int i = 0; i < strlen(str); i++) {
            price = price*10 + (str[i]-'0');
        }
        return price;
    }
    return 0;
}

void Dijkstra() {
    int curNode = 1, maxPrice = 0;

    visited[curNode] = true;
    dist[curNode] = 0;
    for (int cnt = 2; cnt <= n; cnt++) {
        int minDis = INF, minNode = 1;

        for (int i = 1; i <= n; i++) {
            if (!visited[i] && graph[curNode][i]) {
                dist[i] = min(dist[i], (dist[curNode]+graph[curNode][i]));
                if (dist[i] < minDis) {
                    minNode = i;
                    minDis = dist[i];
                }
            }
        }
        maxPrice = max(maxPrice, dist[minNode]);
        curNode = minNode;
        visited[minNode] = true;
    }
    cout << maxPrice << endl;
}

int main() {
    char str[10];

    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        dist[i] = INF;
        visited[i] = false;
    }
    for (int i = 2; i <= n; i++) {
        for (int j = 1; j < i; j++) {
            scanf("%s", str);
            graph[j][i] = graph[i][j] = str_to_price(str);
        }
    }
    Dijkstra();
    return 0;
}

对于求单源最短路径问题,除了Dijkstra,还有一种算法那就是Bellman-Ford算法,不过这种算法效率没有Dijkstra高,但它能够用来解决Dijkstra无法解决的问题,比如图中含有负权边或者是负圈,只能够用Bellman-Ford算法来求解。但是对于这道题目用Bellman-Ford来求解的话会超时,下面是代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;

const int MAXN = 6;
const int INF = 0xfffffff;
int n, graph[MAXN][MAXN], dist[MAXN], inQueen[MAXN];
queue<int> q;

int str_to_price(char *str) {
    int price = 0;

    if (str[0] != 'x') {
        for (int i = 0; i < strlen(str); i++) {
            price = price*10 + (str[i]-'0');
        }
        return price;
    }
    return 0;
}

void Bell_Ford() {
    q.push(1);
    inQueen[1] = true;
    dist[1] = 0;
    while (!q.empty()) {
        int idx = q.front();q.pop();

        inQueen[idx] = false;
        for (int i = 1; i <= n; i++) {
            if (graph[idx][i] && (dist[i] > graph[idx][i]+dist[idx])) {
                dist[i] = graph[idx][i] + dist[idx];
                //下面这两句可以用来判断一个图中是否含有负圈
                //cnt[i] ++;
                //if (cnt[i] == n) cout << "negetive circle" << endl;
                if (!inQueen[i]) {
                    q.push(i);
                    inQueen[i] = true;
                }
            }
        }
    }
    int ans = dist[1];

    for (int i = 2; i <= n; i++) ans = max(ans, dist[i]);
    cout << ans << endl;
}


int main() {
    char str[10];

    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        dist[i] = INF;
        inQueen[i] = false;
    }
    for (int i = 2; i <= n; i++) {
        for (int j = 1; j < i; j++) {
            scanf("%s", str);
            graph[j][i] = graph[i][j] = str_to_price(str);
        }
    }
    Bell_Ford();
    return 0;
}

    原文作者:Bellman - ford算法
    原文地址: https://blog.csdn.net/qq_26347051/article/details/79029063
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞