图论算法(4) --- TSP旅行商问题 求最短回路(acm)

对于TSP旅行商问题,我们做的最多的也就是求最短回路了,那么对于一个数据量适中的图来说,一般的dfs方法即可求解,在这里,我应用dfs的思想来实现此问题,而关键之处在于对矩阵的改进,这样的操作可以使得应用搜索思想求TSP问题时,效率有显著的提高。


对于矩阵的改进,我们对矩阵的处理是,每一行减去所在行的最小值,每一列减去所在列的最小值,并把这些最小值加到结果sum中,这样的操作是将矩阵稀疏化的改进(注意,稀疏化后的矩阵并不一定是稀疏矩阵,不要混淆),再在剩下的矩阵里进行dfs搜索,从而降低了搜索空间,搜索出的结果加到sum中,即是最终的结果。注意,改进过的矩阵不可再次进行重复改进,也就是说所有行所有列减去最小值的操作只能做一次,至于为什么,大家可以思考一下,如有问题,欢迎留言。


附上代码:

#include
#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;
}


你可能感兴趣的:(算法,acm)