POJ 3311 Hie with the Pie (TSP问题 状压DP解法)

TSP问题的状态DP解法:

题意:从1点开始遍历全图的点后回到起点的最短路径问题

因为TSP不限制每个点遍历的次数,所以可以用floyd处理下两点间的距离,之后DP处理下,

DP[i][j]表示状态为二进制i下,当前遍历第j个点的最小值,DP[1<<j][j]初始化为map[0][j]

 

#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;

const int maxn=12;
const int maxm=1<<11|1;

int n;
int map[maxn][maxn];
int dp[maxm][maxn];

void floyd()
{
    for (int k=0 ; k<=n ; ++k)
        for (int i=0 ; i<=n ; ++i)
            for (int j=0 ; j<=n ; ++j)
                if(map[i][j]>map[i][k]+map[k][j])
                    map[i][j]=map[i][k]+map[k][j];
}

int main ()
{
    while (~scanf("%d",&n)&&n)
    {
        for (int i=0 ; i<=n ; ++i)
            for (int j=0 ; j<=n ; ++j)
            {
                scanf("%d",*(map+i)+j);
            }
        floyd();
        memset (dp , 63 , sizeof(dp));
        for (int i=0 ; i<(2<<n) ; ++i)
        {

            for (int j=0 ; j<=n ; ++j)
            {
                dp[1<<j][j]=map[0][j];
                //if(i==1<<j)dp[i][j]=map[0][j];这个和上面的语句都能AC
                if(i&(1<<j))
                    for (int k=0 ; k<=n ; ++k)
                    {
                        if((i-(1<<j)) & (1<<k))//第k位为1,第j位不为1的状态
                        dp[i][j]=min(dp[i-(1<<j)][k]+map[k][j],dp[i][j]);
                    }
                    //printf("%d %d %d\n",i,j,dp[i][j]);
            }

        }
        int ans=dp[(2<<n)-1][0];
        for (int i=1 ; i<=n ; ++i)
        {
            ans=min(dp[(2<<n)-1][i]+map[i][0],ans);
        }
        printf("%d\n",ans);
    }
    return 0;
}


 

你可能感兴趣的:(POJ 3311 Hie with the Pie (TSP问题 状压DP解法))