zoukankan      html  css  js  c++  java
  • 状压DP HDU3538 A sample Hamilton path

    A sample Hamilton path

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 527    Accepted Submission(s): 213


    Problem Description
    Give you a Graph,you have to start at the city with ID zero.
     
    Input
    The first line is n(1<=n<=21) m(0<=m<=3)
    The next n line show you the graph, each line has n integers.
    The jth integers means the length to city j.if the number is -1 means there is no way. If i==j the number must be -1.You can assume that the length will not larger than 10000
    Next m lines,each line has two integers a,b (0<=a,b<n) means the path must visit city a first.
    The input end with EOF.
     
    Output
    For each test case,output the shorest length of the hamilton path.
    If you could not find a path, output -1
     
    Sample Input
    3 0 -1 2 4 -1 -1 2 1 3 -1 4 3 -1 2 -1 1 2 -1 2 1 4 3 -1 1 3 2 3 -1 1 3 0 1 2 3
     
    Sample Output
    4 5
    Hint
    I think that all of you know that a!=b and b!=0 =。=
     
    Source
     
    Recommend
    zhouzeyong
     

    莫名其妙就状压DP了,说实在我现在还不明白这是个什么玩意儿......

    不过尹神说了是典型,那就写一写吧......

    这就是个Floyd么......

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 
     7 int n,m;
     8 int dis[25][25];
     9 int f[2500000];
    10 int dp[2500000][25];//dp[i][j]已访问的点集i 到达点i的最短hamilton 
    11 const int MAX=3000000;
    12 int ans;
    13 
    14 int main(){
    15     int x=0,y=0;
    16     while(scanf("%d%d",&n,&m)!=EOF){
    17         memset(f,0,sizeof(f));
    18         memset(dis,0,sizeof(dis));
    19         memset(dp,0,sizeof(dp)); 
    20         for(int i=0;i<n;i++)
    21             for(int j=0;j<n;j++) scanf("%d",&dis[i][j]);
    22         for(int i=1;i<=m;i++){
    23             scanf("%d%d",&x,&y);
    24             f[y]|=(1<<x);//观察了样例才发现 原来y可以多次出现 
    25         }
    26         for(int i=0;i<(1<<n);i++)
    27             for(int j=0;j<n;j++)  dp[i][j]=MAX;
    28         dp[1][0]=0;
    29         for(int k=0;k<(1<<n);k++)
    30             for(int i=0;i<n;i++)
    31                 if(dp[k][i]!=MAX)
    32                     for(int j=0;j<n;j++){
    33                         if((dis[i][j]==-1)||(!(k&(1<<i)))||(k&(1<<j))||f[j]!=(k&f[j])) continue;//判断是否遍历过 
    34                         dp[k|(1<<j)][j]=min(dp[k|(1<<j)][j],dp[k][i]+dis[i][j]);//f[k][i]->f[k+{j}][j] + dis(i, j) 
    35                     }
    36         ans=MAX;
    37         for(int i=0;i<n;i++) ans=min(ans,dp[(1<<n)-1][i]);
    38         if(ans==MAX) printf("-1
    ");
    39         else printf("%d
    ",ans);
    40     }
    41     return 0;
    42 } 
  • 相关阅读:
    (4) 编译 Android-5.0 源码
    (3) 下载 Android-5.0 源码
    (2) 搭建 Android 系统开发环境
    npm 安装 --save-dev 与 --save的使用与区别
    一点目标
    AcWing 875. 快速幂
    Codeforces Round #604 (Div. 2)
    2019年安徽大学ACM/ICPC实验室新生赛(公开赛)D 不定方程
    C语言黑与白问题
    AcWing 92. 递归实现指数型枚举
  • 原文地址:https://www.cnblogs.com/zwube/p/6790796.html
Copyright © 2011-2022 走看看