求解图的单源最短路径 给定一个带权有向图G=(V,E),其中每条边的权是一个正整数,另外给定一个顶点v作 为源点,求从源点v到其余各顶点的最短路径长度。 请用分枝限界法编程解决之

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <queue>
  4. #include <algorithm>
  5. #define MAX 1000
  6. #define INF 999999999                                      
  7. using namespace std;
  8. struct Node{
  9.     // 顶点编号
  10.     int i;
  11.     // 距离源点的距离
  12.     int len;
  13.     // 优先队列需要重载<运算符
  14.     bool operator<(const Node &a) const
  15.     {
  16.         return len > a.len;
  17.     }
  18. };                                                            
  19. // map[i][j]表示从 i -> j 的路径
  20. int map[MAX][MAX];
  21. // 顶点个数n
  22. int n;
  23. // 源点v
  24. int v;
  25. // 源点v到其余点的距离
  26. int dis[MAX];
  27. // 初始化
  28. void initMap(){                                            
  29.     for(int i=0; i<n; i++){
  30.         for(int j=0; j<n; j++){
  31.             if(i == j){
  32.                 map[i][j] = 0
  33.             }
  34.             else{
  35.                 map[i][j] = INF;
  36.             }
  37.         }
  38.     }
  39. }
  40. // 广度优先搜索
  41. void bfs(){                                              
  42.     priority_queue<Node> minNode
  43.     Node node1;
  44.     node1.i = v;
  45.     node1.len = 0;
  46.     minNode.push(node1);
  47.     // 每次从优先队列中选出距离源点最近的点,通过该点对所有边进行松弛
  48.     while (!minNode.empty())                               
  49.     {
  50.         node1 = minNode.top();
  51.         minNode.pop();
  52.         for(int j=0; j<n; j++){
  53.             if(map[node1.i][j] < INF && (node1.len + map[node1.i][j] < dis[j])){
  54.                 dis[j] = node1.len + map[node1.i][j];
  55.                 Node node2;
  56.                 node2.i = j;
  57.                 node2.len = dis[j];
  58.                 minNode.push(node2);
  59.             }
  60.         }
  61.     }
  62. }                                                     
  63. int main()
  64. {
  65.     int w;
  66.     // 输入顶点的个数,源点,边的个数
  67.     cin >> n >> v >> w;
  68.     // 初始化dis数组
  69.     for(int i=0; i<n; i++){
  70.         dis[i] = INF;
  71.     }                                                    
  72.     dis[v] = 0;
  73.     // 初始化图
  74.     initMap();
  75.     // 输入边的数据,从 x -> y,路径为 z
  76.     for(int i=0; i<w; i++){
  77.         int x, y, z;
  78.         cin >> x >> y >> z;
  79.         map[x][y] = z;
  80.     }
  81.     // 求解
  82.     bfs();
  83.     // 输出
  84.     for(int i=0; i<n; i++){
  85.         if(i != v){
  86.             if(dis[i] == INF){
  87.                 printf("%d -> %d = null\n", v, i, dis[i]);
  88.             }
  89.             else printf("%d -> %d = %d\n", v, i, dis[i]);
  90.         }
  91.     }
  92.     return 0;
  93. }

分支界限法,类似于回溯法,是一种在问题的解空间树T上搜索问题解的算法,在一般情况下,分支界限法和回溯法求解目标不同。回溯法求解目标是找出T中满足约束条件的所有解,而分支界限法的求解目标则是找出满足约束条件的一个解,或是在满足约束条件的解中找出使某一目标函数值达到极大或极小的解,即在某种意义下的最优解

分支搜索算法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值