1. 程式人生 > >圖論演算法(4) --- TSP旅行商問題 求最短迴路(acm)

圖論演算法(4) --- TSP旅行商問題 求最短迴路(acm)

對於TSP旅行商問題,我們做的最多的也就是求最短迴路了,那麼對於一個數據量適中的圖來說,一般的dfs方法即可求解,在這裡,我應用dfs的思想來實現此問題,而關鍵之處在於對矩陣的改進,這樣的操作可以使得應用搜索思想求TSP問題時,效率有顯著的提高。


對於矩陣的改進,我們對矩陣的處理是,每一行減去所在行的最小值,每一列減去所在列的最小值,並把這些最小值加到結果sum中,這樣的操作是將矩陣稀疏化的改進(注意,稀疏化後的矩陣並不一定是稀疏矩陣,不要混淆),再在剩下的矩陣裡進行dfs搜尋,從而降低了搜尋空間,搜尋出的結果加到sum中,即是最終的結果。注意,改進過的矩陣不可再次進行重複改進,也就是說所有行所有列減去最小值的操作只能做一次,至於為什麼,大家可以思考一下,如有問題,歡迎留言。

附上程式碼:

#include<stdio.h>
#define MAX 0x7fffffff
int g[16][16],visit[16],n,ans=MAX,count=1,sum=0;
void dfs(int i,int count,int sum)
{
    int p;
    if(sum>=ans)return;
    if(count==n)
    {
        sum+=g[i][1];
        ans=ans>sum?sum:ans;
        return;
    }
    for(p=1;p<=n;p++)
    {
        if(!visit[p]&&p!=i)
        {
            visit[i]=1;
            dfs(p,count+1,sum+g[i][p]);
            visit[i]=0;
        }
    }
}
int main()
{
    int i,j,min;
    scanf("%d",&n);
    for(i=1;i<=n;i++)
    {
        min=MAX;
        for(j=1;j<=n;j++)
        {
            scanf("%d",&g[i][j]);
            if(j!=i&&min>g[i][j])min=g[i][j];
        }
        if(min!=MAX)
        {
            sum+=min;
            for(j=1;j<=n;j++)if(j!=i)g[i][j]-=min;
        }
    }
    for(j=1;j<=n;j++)
    {
        min=MAX;
        for(i=1;i<=n;i++)if(i!=j&&min>g[i][j])min=g[i][j];
        if(min!=MAX)
        {
            sum+=min;
            for(i=1;i<=n;i++)if(i!=j)g[i][j]-=min;
        }
    }
    visit[1]=1;
    dfs(1,1,sum);
    printf("%d\n",ans);
    return 0;
}