最短Hamilton路径(状态压缩dp)

思路:

(1)需求:所有点都走一遍,且以n-1为尾巴的最短路。

(2)考虑二进制表示各点是否走过;

(3)f[i][j]表示以i为已走过的点,j表示终点这种条件下的最短路;f[i][j]可以分为f[i - (1<

(4)于是枚举i即任意走过的路径可能(1<

(5)初始化:首先f需要初始化为无穷,即不可达,方便更新最小值;其次更新起点f[1][0]即只走过0点,且终点为0的距离为0,以便以后递推更新。

代码:

#include

using namespace std;
const int N = 20,M = 1 << N;
int f[M][N],s[N][N];

int main()
{
    int n;
    cin >> n;
    
    for(int i = 0;i < n;i ++)
        for(int j = 0;j < n;j ++)
            cin >> s[i][j];
    memset(f,0x3f,sizeof f);
    f[1][0] = 0;
    for(int i = 0;i < (1 << n);i ++)   
        for(int j = 0;j < n;j ++)
            if((i >> j &1) == 1)
            {
                for(int k = 0;k < n;k ++)
                {
                    if((i - (1 << j))>>k&1 == 1)
                    {
                        f[i][j] = min(f[i][j],f[(i - (1 << j))][k] + s[k][j]);
                    }
                }
            }
            
    cout << f[(1 << n) - 1][n - 1];
    
    return 0;
}

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