1. 程式人生 > >旅行售貨問題(回溯)

旅行售貨問題(回溯)

演算法設計例題:旅行售貨員問題(回溯、分枝限界)

memory limit: 5000KB    time limit: 2000MS

accept: 4    submit: 5

Description

旅行售貨員問題又稱TSP問題,問題如下:某售貨員要到若干個城市推銷商品,已知各城市之間的路程(或旅費),他要選定一條從駐地出發,經過每個城市一遍最後回到駐地的路線,使總的路線(或總的旅費)最小。數學模型為給定一個無向圖,求遍歷每一個頂點一次且僅一次的一條迴路,最後回到起點的最小花費。

Input

輸入的第一行為測試樣例的個數T( T < 120 ),接下來有T個測試樣例。每個測試樣例的第一行是無向圖的頂點數n、邊數m( n < 12,m < 100 ),接下來m行,每行三個整數u、v和w,表示頂點u和v之間有一條權值為w的邊相連。( 1 <= u < v <= n,w <= 1000 )。假設起點(駐地)為1號頂點。

Output

對應每個測試樣例輸出一行,格式為"Case #: W",其中'#'表示第幾個測試樣例(從1開始計),W為TSP問題的最優解,如果找不到可行方案則輸出-1。

Sample Input

2 5 8 1 2 5 1 4 7 1 5 9 2 3 10 2 4 3 2 5 6 3 4 8 4 5 4 3 1 1 2 10

Sample Output

Case 1: 36 Case 2: -1

Author

Eapink

解決方法:

//旅行售貨員問題  (回溯)
#include<iostream>  
#define N 100  
using namespace std;  
int n,m,w,           //圖的頂點數和邊數
    graph[N][N],     //圖的加權鄰接矩陣
    c=0,             //當前費用
    bestc=-1,         //當前最優值
    x[N],            //當前解
    bestx[N];        //當前最優解
void backtrack(int k);  
void swap(int &a,int &b);  




void swap(int &a,int &b)  
{  
    int temp=a;  
    a=b;  
    b=temp;  
}  
void backtrack(int k)  
{  
    if(k==n)  
    {  
        if( (c+graph[x[n-1]][x[n]]+graph[x[n]][1]<bestc||bestc==-1) && graph[x[n-1]][x[n]]!=-1 && graph[x[n]][1]!=-1 )  
        {  
            bestc=c+graph[x[n-1]][x[n]]+graph[x[n]][1];  
            for(int i=1;i<=n;i++)  
            {  
                bestx[i]=x[i];  
            }  
        }  
        return ;  
    }  
    else  
    {  
        for(int i=k;i<=n;i++)  
        {  
            if( graph[x[k-1]][x[i]]!=-1 && (c+graph[x[k-1]][x[i]]<bestc || bestc==-1))  
            {  
                swap(x[i],x[k]);  
                c+=graph[x[k-1]][x[k]];  
                backtrack(k+1);  
                c-=graph[x[k-1]][x[k]];  
                swap(x[i],x[k]);  
            }  
        }  
    }  





int main(void)  
{  
int i,j,tmp=1,testNum;
cin>>testNum;
while(tmp<=testNum)
{
cin>>n>>m;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
graph[i][j]=-1;
for(int k=1;k<=m;k++)
{
cin>>i>>j>>w;
graph[i][j]=w;
graph[j][i]=w;
}
for(i=1;i<=n;i++)  
{  
x[i]=i;  
bestx[i]=i;  

backtrack(2);  
cout<<"Case "<<tmp<<": "<<bestc<<endl;
bestc=-1;
c=0;

tmp++;
}


return 0;  
}