hdu 5418 Victor and World

经过多年的努力,维克多终于拿到了驾驶执照。为了庆祝一下,他打算给自己买一架飞机,飞遍全世界。地球上有n个国家,编号从1到n。它们由m个无向航班连接,第i次航班详细连接了ui国和vi国,如果Victor飞越这些国家,需要消耗Victor的飞机的燃油。他有可能从第一个国家飞到每一个国家。
Victor现在在一个编号为1的国家,他想知道最少需要多少燃料才能让他至少访问每个国家一次,最后回到第一个国家。

考虑状压dp,\(f_{s,i}\)表示s这个集合里的点全走并且走到i的最短路长,然后就能写出转移方程

\[f_{s,j}=min(f_{s-(1<<j),k} + dis_{k,j})\ ,\ j,k\in s \]

\(dis_{j,k}\)就是j到k的最短路

其实就是像弗洛伊德一样枚举一个断点,然后去更新dp值

而我们是从点0出发的(我是从0~n-1存的点),所以一定要保证\(1\in s\)

最后只要取\(min_{i=1}^{n-1}f_{(1<<n)-1,i}+dis_{i,0}\)就好了

时间复杂度没算错的话应该是\(O(2^{n-1}\times n^2)\)

Code

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
const int N = 16;
using namespace std;
int T,n,m,mp[N + 5][N + 5],f[(1 << N) + 5][N + 5],ans;
int main()
{
    scanf("%d",&T);
    while (T--)
    {
        scanf("%d%d",&n,&m);
        int u,v,w;
        memset(mp,127,sizeof(mp));
        memset(f,127,sizeof(f));
        ans = mp[0][0];        
        for (int i = 0;i < n;i++)
           mp[i][i] = 0;
        for (int i = 1;i <= m;i++)
        {
            scanf("%d%d%d",&u,&v,&w);
            u--,v--;
            if (u != v)
                mp[v][u] = mp[u][v] = min(mp[u][v],w);
        }
        for (int i = 0;i < n;i++)
            for (int j = 0;j < n;j++)
                for (int k = 0;k < n;k++)
                    if (mp[j][i] < mp[n][n] && mp[i][k] < mp[n][n])
                        mp[j][k] = min(mp[j][k],mp[j][i] + mp[i][k]);
        f[1][0] = 0;
        f[0][0] = 0;
        for(int i = 3;i < (1 << n);i++)
            if (i & 1)
            {
                for (int j = 1;j < n;j++)
                    if (i & (1 << j))
                        for (int k = 0;k < n;k++)
                            if (k != j && (i & (1 << k)))
                                f[i][j] = min(f[i][j],f[i - (1 << j)][k] + mp[k][j]);
            }
        for (int i = 1;i < n;i++)
            ans = min(ans,f[(1 << n) - 1][i] + mp[i][0]);
        if (n == 1)
            ans = 0;
        printf("%d\n",ans);
    }
    return 0;
}
posted @ 2020-06-08 21:22  eee_hoho  阅读(24)  评论(0编辑  收藏  举报