📜  门| GATE CS 2013 |问题8(1)

📅  最后修改于: 2023-12-03 14:58:19.936000             🧑  作者: Mango

GATE CS 2013 | 问题 8

本题考查的是图论算法的实现。具体题目如下:

有一个带权无向图G=(V, E),其中权重表示为边的距离。给定源节点s和两个节点t1和t2,找到从s开始到t1和t2的最短路径,假设该图中不存在负权重的边。

代码示例

下面是一个C++实现的代码示例:

#include <iostream>
#include <queue>
#include <vector>
#include <limits>

using namespace std;

typedef pair<int, int> Edge; // pair表示连接两个节点的边和该边的距离
typedef vector<Edge> AdjList; // vector表示表示一个节点的邻接点集合
typedef vector<AdjList> Graph; // vector表示整个图的邻接表

void dijkstra(int start, const Graph& graph, vector<int>& dist) {
    priority_queue<Edge, vector<Edge>, greater<Edge>> pq;
    pq.push(make_pair(0, start));
    dist[start] = 0;

    while(!pq.empty()) {
        Edge curr = pq.top();
        pq.pop();

        int currNode = curr.second;
        int currDist = curr.first;

        if(currDist > dist[currNode]) {
            continue;
        }

        for(auto neighbor : graph[currNode]) {
            int neighborNode = neighbor.first;
            int neighborDist = neighbor.second;

            if(currDist + neighborDist < dist[neighborNode]) {
                dist[neighborNode] = currDist + neighborDist;
                pq.push(make_pair(dist[neighborNode], neighborNode));
            }
        }
    }
}

int main() {
    int n, m;
    cin >> n >> m;

    Graph graph(n);

    for(int i = 0; i < m; i++) {
        int u, v, w;
        cin >> u >> v >> w;

        graph[u].push_back(make_pair(v, w));
        graph[v].push_back(make_pair(u, w));
    }

    int s, t1, t2;
    cin >> s >> t1 >> t2;

    vector<int> distS(n, numeric_limits<int>::max()), distT1(n, numeric_limits<int>::max()), distT2(n, numeric_limits<int>::max());

    dijkstra(s, graph, distS);
    dijkstra(t1, graph, distT1);
    dijkstra(t2, graph, distT2);

    int minDist = distS[t1] + distS[t2];
    for(int i = 0; i < n; i++) {
        minDist = min(minDist, distS[i] + distT1[i] + distT2[i]);
    }

    cout << minDist << endl;

    return 0;
}
简要解释

此代码实现使用了Dijkstra算法来计算最短路径。Dijkstra算法以每个节点的距离为优先级来添加每个节点,并在处理每个节点时更新距离。

在此实现中,我们使用了一个叫做“邻接表”的数据结构,它是一个vector的vector,每个节点都有一个vector,其中包含与该节点相邻的所有节点(顶点)和边距离。

在循环处理每个节点时,我们会将与该节点相邻的边的距离加上当前节点的距离,如果这个距离小于已知的最短距离,则更新此点的距离。此后,我们将处理过的节点添加到优先队列中,以便在下一次迭代中进一步处理。

在主函数中,我们输入图形并针对所有节点调用Dijkstra算法。为此,我们需要三个不同的距离向量(距离向量表示从起始节点到所有其他节点的距离向量),一个定义源点始终为0,其他点始终为正无穷数的距离向量,另外两个用于计算从t1和t2到所有节点的距离。最后,我们打印出s到t1和t2的最短距离之和以及从每个节点到t1和t2的最短距离总和的最小值,即为答案。

Markdown说明

以上是针对问题八的一个C++实现,代码含有详细的注释,几乎没有难以理解的算法。