• bzoj 3055礼物运送 floyed + 状压DP


    bzoj 3055: 礼物运送

    floyed first 设f[i][S]表示取到了S集合中的所有点(不一定是经过的所有点),最后停在了i的最优值。

    初始就f[i][{i}] = dis[1][i]

    状态转移直接转就好了

    f[i][S] + dis[i][j] -> f[j][S + {j}]其中 i 属于 S,1 <= j <= n

    设tim[S] = min{f[i][S]}

    答案就取到

               ans = min{max{tim[S],tim[Cs]}}

     1 #include <map>
     2 #include <queue>
     3 #include <cstdio>
     4 #include <cstring>
     5 #include <climits>
     6 #include <algorithm>
     7 using namespace std;
     8 inline void read(int &x){
     9     x=0;char ch;bool flag = false;
    10     while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
    11     while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
    12 }
    13 inline int cat_min(const int &a,const int &b){return a<b ? a:b;}
    14 inline int cat_max(const int &a,const int &b){return a>b ? a:b;}
    15 inline int cat_abs(const int &x){return x < 0 ? -x : x;}
    16 const int maxn = 19;
    17 const int maxs = (1<<19) + 1;
    18 int dis[maxn][maxn],n,f[maxn][maxs],tim[maxs];
    19 inline void init(){
    20     memset(dis,0x3f,sizeof dis);
    21     memset(f,0x3f,sizeof f);
    22     memset(tim,0x3f,sizeof tim);
    23 }
    24 void floyed(){
    25     for(int i=1;i<=n;++i){
    26         dis[i][i] = 0;
    27         for(int j=1;j<=n;++j){
    28             if(i == j) continue;
    29             for(int k=1;k<=n;++k){
    30                 dis[i][j] = cat_min(dis[i][j],
    31                 dis[i][k] + dis[k][j]);
    32             }
    33         }
    34     }return;
    35 }
    36 map<int,int>ma;
    37 int main(){
    38  
    39     int m;read(n);read(m);
    40     init();
    41     for(int i=1,u,v,d;i<=m;++i){
    42         read(u);read(v);read(d);
    43         if(dis[u][v] > d) dis[u][v] = dis[v][u] = d;
    44     }
    45     floyed();
    46     for(int i=0;i<=18;++i) ma[1<<i] = i+1;
    47     for(int i=1;i<=n;++i) f[i][(1<<0) | (1<<(i-1))] = dis[1][i];
    48     for(int i=0,x=0;i<(1<<n);x = (++i) ){
    49         while(x){
    50             int p = ma[x&-x];x -=x&-x;
    51             for(int j=1;j<=n;++j){
    52                 if( f[j][i | (1<<(j-1))] > f[p][i] + dis[p][j]){
    53                     f[j][i | (1<<(j-1))] = f[p][i] + dis[p][j];
    54                 }
    55             }
    56         }
    57     }
    58     for(int i=0,x=0;i<(1<<n);x = (++i) ){
    59         while(x){
    60             int p = ma[x & -x];x -= x&-x;
    61             tim[i]=cat_min(tim[i],f[p][i]);
    62         }
    63     }
    64     int ans = 0x7f7f7f7f;
    65     for(int i=0;i<(1<<n);++i){
    66         ans = cat_min(ans,cat_max(tim[i],
    67         tim[1 | (( (1 << n)-1 )^i) ]));
    68     }printf("%d
    ",ans);
    69     //getchar();getchar();
    70     fclose(stdin);fclose(stdout);
    71     return 0;
    72 }
    人就像命运下的蝼蚁,谁也无法操控自己的人生.
  • 相关阅读:
    iOS coreData
    具体解释首页被K后SEOer必做的三大排除方法!
    linux VIM基本命令
    0046算法笔记——【随机化算法】舍伍德随机化思想解决跳跃表问题
    android新浪分享实例
    DIV固定在页面某个位置,不随鼠标滚动而滚动
    迷宫问题算法分析
    ExtJs选择器
    第二篇Activity:2、任务和返回堆栈(Tasks and Back Stack)之基本介绍
    面试题,将数字依次按三角形输出,每行一个数字
  • 原文地址:https://www.cnblogs.com/Skyminer/p/6023156.html
Copyright © 2020-2023  润新知