zoukankan      html  css  js  c++  java
  • hdu 4640(状压dp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4640

    思路:f[i][j]表示一个人状态i下走到j的最小花费,dp[i][j]表示i个人在状态j下的最下花费。首先我们可以一遍bfs求出f[i][j],然后通过f[i][j]得到dp[1][i],最后就是更新dp[i][j]了。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<queue>
     6 using namespace std;
     7 #define inf 1<<30
     8 typedef pair<int,int>PP;
     9 
    10 int map[20][20];
    11 int f[1<<18][20];//派一个人去,在某状态下到达点v的最小花费
    12 int dp[4][1<<18];//派i个人去,在某状态的最小花费
    13 bool mark[1<<18][20];
    14 int n,m,S,ans;
    15 
    16 void bfs()
    17 {
    18     queue<PP>que;
    19     que.push(make_pair(0,0));
    20     memset(mark,false,sizeof(mark));
    21     for(int i=0;i<(1<<n);i++)
    22         for(int j=0;j<n;j++)f[i][j]=inf;
    23     f[0][0]=0;
    24     while(!que.empty()){
    25         PP p=que.front();
    26         que.pop();
    27         int s=p.first,u=p.second;
    28         mark[s][u]=false;
    29         for(int i=0;i<n;i++){
    30             if(map[u][i]<inf&&f[s|(1<<i)][i]>f[s][u]+map[u][i]){
    31                 f[s|(1<<i)][i]=f[s][u]+map[u][i];
    32                 if(!mark[s|(1<<i)][i]){
    33                     mark[s|(1<<i)][i]=true;
    34                     que.push(make_pair(s|(1<<i),i));
    35                 }
    36             }
    37         }
    38     }
    39 }
    40 
    41 void Solve()
    42 {
    43     for(int i=1;i<=3;i++)
    44         for(int j=0;j<(1<<n);j++)dp[i][j]=inf;
    45     for(int i=0;i<(1<<n);i++)
    46         for(int j=0;j<n;j++)dp[1][i]=min(dp[1][i],f[i][j]);
    47     for(int i=2;i<=3;i++){
    48         for(int j=0;j<(1<<n);j++){
    49             //枚举子集
    50             for(int k=j;k;k=(k-1)&j){
    51                 dp[i][j]=min(dp[i][j],max(dp[1][k|1],dp[i-1][(j^k)|1]));
    52             }
    53         }
    54     }
    55     ans=inf;
    56     for(int i=1;i<=3;i++)
    57         for(int j=0;j<(1<<n);j++)if((j&S)==S)ans=min(ans,dp[i][j]);
    58     if(ans==inf)ans=-1;
    59     printf("%d
    ",ans);
    60 }
    61 
    62 int main()
    63 {
    64     int _case,u,v,w,k,t=1;
    65     scanf("%d",&_case);
    66     while(_case--){
    67         scanf("%d%d",&n,&m);
    68         for(int i=0;i<=n;i++)
    69             for(int j=0;j<=n;j++)map[i][j]=(i==j?0:inf);
    70         while(m--){
    71             scanf("%d%d%d",&u,&v,&w);
    72             u--,v--;
    73             map[u][v]=map[v][u]=min(map[u][v],w);
    74         }
    75         S=0;
    76         scanf("%d",&k);
    77         while(k--){
    78             scanf("%d",&u);
    79             u--;
    80             S|=(1<<u);
    81         }
    82         bfs();
    83         printf("Case %d: ",t++);
    84         Solve();
    85     }
    86     return 0;
    87 }
    88 
    89 
    90 
    91             
    View Code
  • 相关阅读:
    C语言-第32课
    typeof和clamp
    C语言void*和*p的使用
    C语言二级指针和一级指针
    C语言结构体变量成员之指针变量成员的坑
    控制硬件三部曲
    C语言const char*使用
    jiffies是什么
    TPO3-1 Architecture
    相关关系|相关系数|线性关系|
  • 原文地址:https://www.cnblogs.com/wally/p/3330414.html
Copyright © 2011-2022 走看看