• 拓扑排序和最短路径结合的一个问题


    关注 码龄 粉丝数 原力等级 -- 被采纳 被点赞 采纳率 Violet516524 2024-06-15 14:51 采纳率: 0% 浏览 2 首页/ 编程语言 / 拓扑排序和最短路径结合的一个问题 c++ 问问各位这个程序应该怎么设计啊Orz,怎么兼顾拓扑序和最短路呢,实在不会了 收起 写回答 好问题 0 提建议 追加酬金 关注问题 微信扫一扫 点击复制链接 分享 邀请回答 编辑 收藏 删除 结题 收藏 举报 追加酬金 (90%的用户在追加酬金后获得了解决方案) 当前问题酬金 ¥ 0 (可追加 ¥500) ¥ 15¥ 20¥ 50¥ 100¥ 200 支付方式 扫码支付 二维码出错 点击刷新 支付金额 15 元 提供问题酬金的用户不参与问题酬金结算和分配 支付即为同意 《付费问题酬金结算规则》 结题 再想想 删除 再等等

    1条回答 默认 最新

    • 阿里嘎多学长 2024-06-15 15:15
      关注

      以下内容由CHATGPT及阿里嘎多学长共同生成、有用望采纳:


      这个问题实际上是一个图论问题,涉及到两个关键的算法:拓扑排序和最短路径。拓扑排序用于确定一个线性的顺序,使得所有有向边都从排序靠前的顶点指向排序靠后的顶点。最短路径算法用于在给定的图中找到从一个顶点到另一个顶点的最短路径。

      程序设计思路:

      1. 输入处理:首先,接收用户输入的地点和游览顺序限制。

      2. 图的构建:将地点作为顶点,游览顺序限制作为有向边构建一个有向图。

      3. 检测环:在图中检测是否存在环。如果存在环,说明无法进行拓扑排序,需要报错或提示用户。

      4. 拓扑排序:如果无环,对图进行拓扑排序,确定一个有效的参观顺序。

      5. 最短路径计算:对于拓扑排序后的顺序,使用最短路径算法(如Dijkstra算法或Bellman-Ford算法)计算从源点到每个顶点的最短路径。

      6. 总路径长度计算:累加从源点到每个顶点的最短路径长度,得到总路径长度。

      7. 输出结果:输出有效的参观顺序和总路径长度。

      C++实现示例:

      #include 
      #include 
      #include 
      #include 
      
      using namespace std;
      
      // 检测图中是否存在环
      bool hasCycle(const vector>& graph) {
          vector visited(graph.size(), false);
          vector recStack(graph.size(), false);
          
          for (int i = 0; i < graph.size(); ++i) {
              if (hasCycleUtil(i, visited, recStack, graph)) {
                  return true;
              }
          }
          return false;
      }
      
      bool hasCycleUtil(int v, vector& visited, vector& recStack, const vector>& graph) {
          visited[v] = true;
          recStack[v] = true;
      
          for (int neighbor : graph[v]) {
              if (!visited[neighbor]) {
                  if (hasCycleUtil(neighbor, visited, recStack, graph)) {
                      return true;
                  }
              } else if (recStack[neighbor]) {
                  return true;
              }
          }
      
          recStack[v] = false;
          return false;
      }
      
      // 拓扑排序
      vector topologicalSort(int V, vector>& graph) {
          vector indegree(V, 0);
          for (const auto& edges : graph) {
              for (int edge : edges) {
                  indegree[edge]++;
              }
          }
      
          queue q;
          for (int i = 0; i < V; ++i) {
              if (indegree[i] == 0) {
                  q.push(i);
              }
          }
      
          vector topOrder;
          while (!q.empty()) {
              int v = q.front();
              q.pop();
              topOrder.push_back(v);
              for (int neighbor : graph[v]) {
                  indegree[neighbor]--;
                  if (indegree[neighbor] == 0) {
                      q.push(neighbor);
                  }
              }
          }
      
          if (topOrder.size() != V) {
              throw runtime_error("Cycle detected, no topological order exists.");
          }
      
          return topOrder;
      }
      
      // Dijkstra算法计算最短路径
      vector dijkstra(int src, int V, vector>>& graph) {
          vector dist(V, numeric_limits::max());
          priority_queue, vector>, greater>> pq;
          dist[src] = 0;
          pq.push({0, src});
      
          while (!pq.empty()) {
              int u = pq.top().second;
              pq.pop();
      
              for (auto& edge : graph[u]) {
                  int v = edge.first;
                  int weight = edge.second;
                  if (dist[v] > dist[u] + weight) {
                      dist[v] = dist[u] + weight;
                      pq.push({dist[v], v});
                  }
              }
          }
      
          return dist;
      }
      
      int main() {
          // 示例输入
          int m = 8; // 地点数量
          vector places = {"蓝球场", "游泳池", "毛主席像", "图书馆", "河西食堂", "理科大楼", "体育馆", "文史楼"};
          int n = 4; // 游览顺序限制数量
          vector> graph(m);
      
          // 这里需要根据输入构建图和游览顺序限制
          // ...
      
          // 检测环
          if (hasCycle(graph)) {
              cout << "存在环,无法进行拓扑排序。" << endl;
              return 1;
          }
      
          // 拓扑排序
          vector topOrder = topologicalSort(m, graph);
      
          // 转换地点名称到索引
          map placeToIndex;
          for (int i = 0; i < places.size(); ++i) {
              placeToIndex[places[i]] = i;
          }
      
          // 构建带权重的图
          vector>> weightedGraph(m);
          // 这里需要根据输入构建带权重的图
          // ...
      
          // 计算最短路径
          vector shortestPaths = dijkstra(placeToIndex["蓝球场"], m, weightedGraph);
      
          // 输出结果
          cout << "有效参观顺序:";
          for (int index : topOrder) {
              cout << places[index] << " ";
          }
          cout << endl;
          cout << "总路径长度:" << shortestPaths[placeToIndex["文史楼"]] << endl;
      
          return 0;
      }
      

      参考资料:

      请注意,上述代码是一个简化的示例,实际实现时需要根据具体输入构建图,并处理输入输出的细节。

      展开全部

      评论 编辑记录
      Violet516524 2024-06-15 16:07

      这个有效参观顺序不一定是总路径长度最短的吧

      回复
      编辑
      预览

      报告相同问题?

    • 相关阅读:
      【MySQL】索引的作用及知识储备
      LeetCode: 数组峰值与谷值问题总结 - Python
      MVC模式
      Spring系列文章:面向切面编程AOP
      为什么低碳水饮食对减肥有效?给你科学的解释
      八股文-TCP的三次握手
      TS类中初始化属性语法糖
      抓包day1
      git实用技巧:把我的文件内容改回去
      Thanos Receiver
    • 原文地址:https://ask.csdn.net/questions/8118969