zoukankan      html  css  js  c++  java
  • tsp问题

       旅行商问题(tsp问题)就是一个经销商从n个城市中的某一城市出发,不重复的走完其余的n-1个城市并回原出发点,求所有可能路径单中走出路径长度最短的一条。

     本题假设旅行商从第一个城市出发。

      解法:dfs+回溯

    #include <iostream>
    
    using namespace std;
    
    #define NUM 100
    
    int n;//图G的顶点数
    int m;//图G的边数
    int a[NUM][NUM];//图G的邻接矩阵
    int x[NUM] = {0}; //当前解
    int bestx[NUM];//最优解
    int cc = 0; //当前费用
    int bestc = 0; //当前最优值
    int NoEdge = -1; //无边标记
    int Visited[100];//访问标志
    int num = 0;
    
    int FirstArc(int t)
    {
        for(int i = 1; i <= m; i++)
            if(a[t][i] != NoEdge)
                return i;
        return 0;
    }
    
    int NextArc(int t, int w)
    {
        for(int p = w + 1; p <= m; p++)
            if(a[t][p] != NoEdge)
                return p;
        return 0;
    }
    
    void dfs(int t)
    {
        int l, i;
        Visited[t] = 1;
    
        if(num == m && a[t][1] != NoEdge)
        {
            if(cc + a[t][1] < bestc)
            {
                bestc = cc + a[t][1];
                for(int s = 0; s < m; s++)
                    bestx[s] = x[s];
            }
        }
        else
        {
            for(i = FirstArc(t); i != 0; i = NextArc(t, i))
                if(!Visited[i] && a[t][i] != NoEdge)
                    if(cc + a[t][i] < bestc) //剪枝
                    {
                        x[num++] = i;
                        cc += a[t][i];
                        dfs(i);
                        cc -= a[t][i];
                        Visited[i] = 0;
                        num--;
                    }
        }
    }
    
    void tsp(int t)
    {
        for(int i = 1; i <= m; i++)
            Visited[i] = 0;
    
        //保存第一个节点
        x[num++] = t;
        Visited[t] = 1;
    
        for(int q = FirstArc(t); q != 0; q = NextArc(t, q))
            if(a[t][q] != NoEdge && !Visited[q])
            {
                x[num++] = q;
                cc += a[t][q];
                dfs(q);
                cc -= a[t][q]; //回溯
                Visited[q] = 0;
                num--;
            }
    }
    
    
    int main()
    {
        int s, e, t;
        scanf("%d%d", &m, &n);
        //初始化邻接矩阵
        for(int i = 1; i <= m; i++)
            for(int j = 1; j <= m; j++)
                a[i][j] = NoEdge;    //表示两个节点不相连
    
        for(int i = 1; i <= n; i++)
        {
            scanf("%d%d%d", &s, &e, &t);
            a[s][e] = t;
            a[e][s] = t;
        }
        //初始化变量
        bestc = 1000;
        tsp(1);
    
        for(int i = 0; i < m; i++)
            printf("%d ", bestx[i]);
    
        printf("
    bestc=%d
    ", bestc);
        return 0;
    }
    
    /*
    1 2 20
    1 4 4
    1 3 6
    2 3 5
    2 4 10
    3 4 15
    
    */
    




  • 相关阅读:
    每天一道LeetCode--141.Linked List Cycle(链表环问题)
    每天一道LeetCode--119.Pascal's Triangle II(杨辉三角)
    每天一道LeetCode--118. Pascal's Triangle(杨辉三角)
    CF1277D Let's Play the Words?
    CF1281B Azamon Web Services
    CF1197D Yet Another Subarray Problem
    CF1237D Balanced Playlist
    CF1239A Ivan the Fool and the Probability Theory
    CF1223D Sequence Sorting
    CF1228D Complete Tripartite
  • 原文地址:https://www.cnblogs.com/gaot/p/7709712.html
Copyright © 2011-2022 走看看