• 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,kin s ]

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

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

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

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

    时间复杂度没算错的话应该是(O(2^{n-1} imes 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
    ",ans);
        }
        return 0;
    }
    
  • 相关阅读:
    iOS
    iOS
    iOS
    OpenGLES入门笔记四
    OpenGLES入门笔记三
    AVPlayer无法播放
    阿里云TTS重播报pointer being freed was not allocated错误
    [AVAssetWriter startWriting] Cannot call method when status is 1
    HTTP load failed (error code: -1009) / NSURLConnection finished with error
    在iPhone5上起始页卡着不动
  • 原文地址:https://www.cnblogs.com/sdlang/p/13068269.html
Copyright © 2020-2023  润新知