zoukankan      html  css  js  c++  java
  • HDU Victor and World (最短路+状态压缩)

    题目链接:传送门 

    题意:

    n个城市m条路。刚開始在点1,求把每一个城市都遍历一边最后回到1的花费的最小值。

    分析:

    我们首先须要预处理出随意两个国家之间的最短距离。由于数据范围非常小,所以直接用Floyd即可了。之后,我们用f[S][i]表示訪问国家的情况为S,当前最后訪问的一个国家是i所须要的最小总油量。当中。S的二进制表示记录了訪问国家的情况,S在二进制表示下的第i位(无论是从左往右还是从右往左都能够)假设是1则表示第i个国家被訪问过了,否则表示第i个国家没有被訪问过,那么f[S|(1<<i)][i]=min(f[S][j]+f[i][j])。当中i和j满足S&(1<<j)=1且S&(1<<i)=0。最開始时,除了f[1][1]是0,其它情况都是无穷大,之后先枚举S,再枚举i(我验题的时候由于这里搞反结果WA了)。那么终于的答案就是min(f[(1<<n)-1][i]+f[i][1])。当中i∈in [2,n]。

    总复杂度为O(n3+n2∗2n)O(n^3+n^2*2^n)O(n3+n22n)

    转自Bestcode。

    以下说说我的状态转移,首先也处理好了每两个城市之间的最短路。

    然后DP[S][J]S转换成二进制后1代表去过,0代表没有去过最后留在J的最小花费,然后就枚举S没有去过的城市k

    DP[S|(1<<k)][k]=min(DP[S][j]+mp[j][k])

    代码例如以下:

    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <cstdio>
    using namespace std;
    
    const int maxn = 18;
    
    const int inf = 0x3f3f3f3f;
    
    int dp[1<<maxn][maxn];
    
    int mp[maxn][maxn];
    
    void init(){
        memset(dp,inf,sizeof(dp));
        for(int i=0;i<maxn;i++)
            for(int j=0;j<maxn;j++)
                mp[i][j]=inf;
    }
    
    int main()
    {
        int t,n,m;
        scanf("%d",&t);
        while(t--){
            init();
            scanf("%d%d",&n,&m);
            for(int i=0;i<m;i++){
                int u,v,w;
                scanf("%d%d%d",&u,&v,&w);
                mp[u][v]=min(mp[u][v],w);
                mp[v][u]=min(mp[v][u],w);
            }
            for(int i=0;i<maxn;i++) mp[i][i]=0;
            for(int k=1;k<=n;k++){
                for(int i=1;i<=n;i++){
                    for(int j=1;j<=n;j++){
                        mp[i][j]=min(mp[i][j],mp[i][k]+mp[k][j]);
                    }
                }
            }
            dp[1][1]=0;
            for(int i=0;i<(1<<n);i++){
                for(int j=0;j<n;j++){
                    if(!(i&(1<<j))){
                        for(int k=1;k<=n;k++){
                            dp[i|(1<<j)][j+1]=min(dp[i|(1<<j)][j+1],dp[i][k]+mp[k][j+1]);
                        }
                    }
                }
            }
            int ans = inf;
            for(int i=1;i<=n;i++)
                ans = min(ans,dp[(1<<n)-1][i]+mp[i][1]);
            printf("%d
    ",ans);
        }
        return 0;
    }
    


  • 相关阅读:
    log4j的使用
    关于spring读取配置文件的两种方式
    BeanUtils组件的使用
    javaee 自定义标签实战
    javaweb中的标签的核心标签库的常用标签
    对接口的思考
    二分查找
    java抽象类
    多例集合
    js中for循环的研究
  • 原文地址:https://www.cnblogs.com/gccbuaa/p/6939622.html
Copyright © 2011-2022 走看看