旅行商问题,bfs + 优先队列

心得:
dfs 转 bfs 的要点:

  1. 在dfs中控制回溯的分支的循环中,将向下层递归的语句改为压入队列(一般借助结构体保存各种环境信息)。
  2. bfs使用优先队列可以剪掉大部分的无用分支。
//图的结点没有出边则表示没回路
//优先队列可以剪掉大部分的无用分支
#include
#include
#include
#include
#include
using namespace std;
#define N 10
struct Node{
    int v;
    int len;
    int x[N];
    int rl;
    int sl;
    Node(int v_ = 0,int len_ = 0,int rl_ = 0):v(v_),len(len_),rl(rl_){}
    bool operator <(const Node& t1) const{
        return this ->sl > t1.sl;  //< 大值优先,  '>'小值优先
    }
};
int n,e;
int m[N][N];
int bestx[N];
int bestl;
int minlen[N];
int mintotal;
void bfs(int setup){
    priority_queue<Node> q;
    Node newnode,t;
    for(int i = 1; i <= n; i++){
        newnode.x[i] = i;
    }
    newnode.v = 2;
    newnode.len = 0;
    newnode.rl = mintotal;
    newnode.sl = mintotal;
    q.push(newnode);
    while(!q.empty()){
        t = q.top();
        q.pop();
        int floor = t.v;
        if(t.v == n + 1){
            if(m[t.x[floor - 1]][setup] != INT_MAX){
                bestl = t.len + m[t.x[floor - 1]][setup];
                for(int i = 1; i <= n; i++){
                    bestx[i] = t.x[i];
                }
                bestx[n + 1] = setup;
                return ;
            }
        }
        for(int i = floor; i<= n; i++){
            if(m[t.x[floor - 1]][t.x[i]] != INT_MAX && t.sl < bestl){
                newnode.v = floor + 1;
                newnode.len = t.len + m[t.x[floor - 1]][t.x[i]];
                newnode.rl -= minlen[t.x[i]];
                newnode.sl = newnode.rl + newnode.len;
                for(int j = 1; j <= n; j++){
                    newnode.x[j] = t.x[j];
                }
                swap(newnode.x[i],newnode.x[floor]);
                q.push(newnode);
            }
        }
    }
}
int main(){
    cin >> n >> e;
    for(int i = 0; i <= n; i++){
        minlen[i] = INT_MAX;
        for(int j = 0; j <= n; j++){
            m[i][j] = INT_MAX;
        }
    }
    for(int i = 0; i < e; i++){
        int v,u,len;
        cin >> v >> u >> len;
        m[v][u] = len;
        m[u][v] = len;
        minlen[v] = min(minlen[v], m[v][u]);
        minlen[u] = min(minlen[u], m[u][v]);
    }
    for(int i = 1; i <= n; i++){
        mintotal += minlen[i];
    }
    bestl = INT_MAX;
    bfs(1);
    for(int i = 1; i <= n + 1; i++){
        cout << bestx[i] << " ";
    }
    cout << endl;
    cout << bestl << endl;
}

/*
4 6
1 2 15
1 3 30
1 4 5
2 3 6
2 4 12
3 4 3
*/

你可能感兴趣的:(队列,dfs,bfs)