TSP 问题的DFS解法(有向无环DAG)(C++)

(写作业的同时记录下来以方便以后学习)(用codeblocks注释更清晰)

#include<iostream>
using namespace std;
#define CityNum 10
int Min = 10000;  //最短路径长度
int Graph[CityNum][CityNum]; //距离邻接表
int CR[CityNum];
int FR[CityNum];
int visit[CityNum] = {0};//初始化标记数组
void DFS(int sum,int start,int n)//n表示此次DFS时CR中已经有的城市个数
{
   for(int i = 0;i<CityNum;i++)
   {
       if(!visit[i])  //若下标为i的点未被访问
       {
           visit[i] = 1;//访问该点
           CR[n] = i;   //将下标为i的点加入到当前路径
           if(n!=CityNum-1)    ///说明此次DFS时已经有9个城市,只差最后一个,所以直接跳转到sum+G[start][i]与Min比较
           {


                               ///注意,递归出口必须单独提出来,即,最后到达的
                               ///城市必须单独拿出来进行比较,否则递归没有出口


               DFS(sum+Graph[start][i],i,n+1);///递归调用时起点变为当前已经加到CR[]的城市,即下标为i 的城市
               visit[i] = 0;//删除访问标记用来下一次使用
           }
           else        //当前路径已经包含所有的城市
           {
               if(sum+Graph[start][i]<Min)   ///如何确定sum+G[start][i]就是所有城市间的距离和?
               {                             ///因为已经有n==9了,说明已经有9个城市在其中了,只需要再加一个
                   Min = sum+Graph[start][i];
                   for(int j = 0;j<CityNum;j++)
                       FR[j]=CR[j];   //更新路径顺序
                   visit[i] = 0;   //删除访问标记
               }
               else
               {
                    visit[i] = 0;   ///当前路径并未比最短路径短,此时只用删除访问记录不用更新FR[]数组和Min
               }
           }
       }
       ///当未被访问过时才会访问以及更改标记,访问过就不用更改标记了,所以没有else语句
   }
}
void DAG_DFS()
{
    int sum,n;
    for(int i = 0;i<CityNum;i++)
    {
        CR[0] = i;///记录第一个访问的城市下标!!!
        sum = 0; //初始化路径总长
        n = 0;   //初始化当前路径总共经过的城市个数
        visit[i] = 1; //起点为下标为i的点,并标记已被访问
        DFS(sum,i,n+1);//n+1表示此次DFS时CR中已经有的城市个数
        visit[i] = 0;   ///删除访问痕迹!!
    }
    cout <<"最短路径长度为:" << Min << "\n";
    for(int i = 0;i<CityNum-1;i++)
        cout<<FR[i]<<"->";
    cout<<FR[CityNum-1];
}
int main()
{
    cout<<"----------输入城市距离的邻接表-----------\n";
    for(int i = 0;i<CityNum;i++)
        for(int j = 0;j<CityNum;j++)
            cin>>Graph[i][j];
    int visit[CityNum] = {0}; //初始化标记数组
    DAG_DFS();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值