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

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


    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,详解见代码
     1 /**/
     2 #include<iostream>
     3 #include<cstdio>
     4 #include<cmath>
     5 #include<cstring>
     6 #include<algorithm>
     7 using namespace std;
     8 const int INF=1e6;
     9 const int mxn=4194304;//2^22
    10 int dp[mxn][22];//[遍历状态][最后到达点]=最短路径 
    11 int dis[22][22];
    12 int pre[22];//每个点的前驱要求 
    13 int n,m;
    14 int xn;
    15 int main(){
    16     while(scanf("%d%d",&n,&m)!=EOF){
    17         memset(pre,0,sizeof pre);
    18         int i,j;
    19         xn=1<<n;
    20         for(i=1;i<xn;i++)
    21          for(j=0;j<n;j++){
    22              dp[i][j]=INF;
    23          }
    24         //init
    25         for(i=0;i<n;i++)
    26          for(j=0;j<n;j++){
    27              scanf("%d",&dis[i][j]);
    28              if(dis[i][j]==-1)dis[i][j]=INF;
    29          }
    30         int u,v;
    31         for(i=1;i<=m;i++){//保存前驱要求 
    32             scanf("%d%d",&u,&v);
    33             pre[v]|=(1<<u);
    34         }
    35         dp[1][0]=0;
    36         for(i=1;i<xn;i++){
    37             for(j=0;j<n;j++){
    38                 if(dp[i][j]==INF)continue;//i状态之前没走到 
    39                 for(int k=1;k<n;k++){
    40                     if(!(i&(1<<j)))continue;//j不在已走过的集合中
    41                     if(i&(1<<k))continue;//k在走过的集合中
    42                     if(pre[k]!=(i&pre[k]))continue;//k点前驱要求未满足 
    43                     dp[i|(1<<k)][k]=min(dp[i|(1<<k)][k],dp[i][j]+dis[j][k]);
    44                 }
    45             }
    46         }
    47         int ans=INF;
    48         for(i=0;i<n;i++)ans=min(ans,dp[xn-1][i]);
    49         if(ans>=INF) printf("-1
    ");
    50         else printf("%d
    ",ans);
    51     }
    52     return 0;
    53 }
  • 相关阅读:
    Codeforces Gym 101142C:CodeCoder vs TopForces(搜索)
    L2-011. 玩转二叉树
    zoj 2976 Light Bulbs(暴力枚举)
    ZOJ 2975 Kinds of Fuwas(暴力+排列组合)
    ZOJ-2972-Hurdles of 110m(线性dp)
    ZOJ 2971 Give Me the Number (模拟,字符数组的清空+map)
    zoj 2966 Build The Electric System(最小生成树)
    ZOJ 2965 Accurately Say "CocaCola"!(预处理)
    HDU 3452 Bonsai(树形dp)
    zoj 3212 K-Nice(构造)
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/5726963.html
Copyright © 2011-2022 走看看