- #include <iostream>
- #include <cstdio>
- #include <queue>
- #include <algorithm>
- #define MAX 1000
- #define INF 999999999
- using namespace std;
- struct Node{
- // 顶点编号
- int i;
- // 距离源点的距离
- int len;
- // 优先队列需要重载<运算符
- bool operator<(const Node &a) const
- {
- return len > a.len;
- }
- };
- // map[i][j]表示从 i -> j 的路径
- int map[MAX][MAX];
- // 顶点个数n
- int n;
- // 源点v
- int v;
- // 源点v到其余点的距离
- int dis[MAX];
- // 初始化
- void initMap(){
- for(int i=0; i<n; i++){
- for(int j=0; j<n; j++){
- if(i == j){
- map[i][j] = 0;
- }
- else{
- map[i][j] = INF;
- }
- }
- }
- }
- // 广度优先搜索
- void bfs(){
- priority_queue<Node> minNode
- Node node1;
- node1.i = v;
- node1.len = 0;
- minNode.push(node1);
- // 每次从优先队列中选出距离源点最近的点,通过该点对所有边进行松弛
- while (!minNode.empty())
- {
- node1 = minNode.top();
- minNode.pop();
- for(int j=0; j<n; j++){
- if(map[node1.i][j] < INF && (node1.len + map[node1.i][j] < dis[j])){
- dis[j] = node1.len + map[node1.i][j];
- Node node2;
- node2.i = j;
- node2.len = dis[j];
- minNode.push(node2);
- }
- }
- }
- }
- int main()
- {
- int w;
- // 输入顶点的个数,源点,边的个数
- cin >> n >> v >> w;
- // 初始化dis数组
- for(int i=0; i<n; i++){
- dis[i] = INF;
- }
- dis[v] = 0;
- // 初始化图
- initMap();
- // 输入边的数据,从 x -> y,路径为 z
- for(int i=0; i<w; i++){
- int x, y, z;
- cin >> x >> y >> z;
- map[x][y] = z;
- }
- // 求解
- bfs();
- // 输出
- for(int i=0; i<n; i++){
- if(i != v){
- if(dis[i] == INF){
- printf("%d -> %d = null\n", v, i, dis[i]);
- }
- else printf("%d -> %d = %d\n", v, i, dis[i]);
- }
- }
- return 0;
- }
分支界限法,类似于回溯法,是一种在问题的解空间树T上搜索问题解的算法,在一般情况下,分支界限法和回溯法求解目标不同。回溯法求解目标是找出T中满足约束条件的所有解,而分支界限法的求解目标则是找出满足约束条件的一个解,或是在满足约束条件的解中找出使某一目标函数值达到极大或极小的解,即在某种意义下的最优解。