📜  门|门CS 2010 |问题 5(1)

📅  最后修改于: 2023-12-03 15:12:47.297000             🧑  作者: Mango

题目介绍

这是一个名为“门”(Door)的游戏,是清华大学2010级CS专业数据结构课程的结课作业。

该游戏的主要目标是在“门”(即图形的边缘)中找到从起点到终点(两个绿色点)的最短路径。

此外,还需要注意以下几点:

  • 过程中可以任意选择蓝色节点作为路径中的中间节点或绝路节点
  • 如果在随意选择的蓝色节点旁边出现了“黑洞”,则游戏失败
  • 如果无法找到有效路径,则游戏失败

解题思路

该题目的主要难点在于寻找图中的最短路径。可以使用Dijkstra算法进行解决。

除此之外,还需要注意以下几个细节:

  • 每个节点的周围节点需要经过边的权值计算,进行路径长度的逐步累加
  • 在保存每个节点的时候,同时需要保存该节点的前继节点,以便在最后输出路径的时候使用
  • 在遍历完所有的节点之后,需要借助已保存的前继节点,从终点向起点回溯一遍,输出最短路径

代码实现

以下是该题目Dijkstra算法的Cpp代码实现,在主函数中输入图的结构体数组data[]和节点的总数N,即可输出起点到终点的最短路径:

void Dijkstra(DATA data[], int N, int start, int end) {
    int* dist = new int[N];
    bool* mark = new bool[N];
    for (int i = 0; i < N; i++) {
        dist[i] = MAX;
        mark[i] = false;
    }
    dist[start] = 0;
    int k, u;
    for (int i = 0; i < N; i++) {
        int minDist = MAX;
        for (int j = 0; j < N; j++) {
            if (!mark[j] && dist[j] < minDist) {
                minDist = dist[j];
                k = j;
            }
        }
        if (minDist == MAX) break;
        mark[k] = true;
        for (int j = 0; j < N; j++) {
            if (!mark[j] && data[k].adj[j] != MAX) {
                int newDist = dist[k] + data[k].adj[j];
                if (newDist < dist[j]) {
                    dist[j] = newDist;
                    data[j].pre = k;
                }
            }
        }
    }
    vector<int> path;
    path.push_back(end);
    int index = end;
    while (index != start) {
        index = data[index].pre;
        path.insert(path.begin(), index);
    }
    for (int i = 0; i < path.size(); i++) {
        cout << path[i] << "->";
    }
    delete[] dist;
    delete[] mark;
}

注:该段代码尽在表现Dijkstra算法部分逻辑的同时,并未包括所有程序文件和完整代码,同时也未包括完整测试代码。