zoukankan      html  css  js  c++  java
  • HDU 3001 三进制 状压dp

    Travelling

    Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3789    Accepted Submission(s): 1182

    Problem Description
    After coding so many days,Mr Acmer wants to have a good rest.So travelling is the best choice!He has decided to visit n cities(he insists on seeing all the cities!And he does not mind which city being his start station because superman can bring him to any city at first but only once.), and of course there are m roads here,following a fee as usual.But Mr Acmer gets bored so easily that he doesn't want to visit a city more than twice!And he is so mean that he wants to minimize the total fee!He is lazy you see.So he turns to you for help.
     
    Input
    There are several test cases,the first line is two intergers n(1<=n<=10) and m,which means he needs to visit n cities and there are m roads he can choose,then m lines follow,each line will include three intergers a,b and c(1<=a,b<=n),means there is a road between a and b and the cost is of course c.Input to the End Of File.
     
    Output
    Output the minimum fee that he should pay,or -1 if he can't find such a route.
     
    Sample Input
    2 1 1 2 100 3 2 1 2 40 2 3 50 3 3 1 2 3 1 3 4 2 3 10
     
    Sample Output
    100 90 7
     
    Source
     
    Recommend
    gaojie
     

    题意:

         ACMer 想要游玩n个城市,告诉我们每个城市间的旅行费用,并且要求每个城市最多走两遍!问最小花费是多少 ?!

    思路:

       典型的TSP问题,唯一的变化就是走两遍!

    解法:

       利用三进制将边点j 在点集i 出现的次数表示成 tir[i][j];

      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdlib>
      4 #include<cstdio>
      5 #include<algorithm>
      6 #include<cmath>
      7 #include<queue>
      8 #include<map>
      9 #include<vector>
     10 #include<set>
     11 
     12 #define N 1005
     13 #define M 100000
     14 #define inf 1000000007
     15 #define mod 1000000007
     16 #define mod2 100000000
     17 #define ll long long
     18 #define maxi(a,b) (a)>(b)? (a) : (b)
     19 #define mini(a,b) (a)<(b)? (a) : (b)
     20 
     21 using namespace std;
     22 
     23 int n;
     24 int m;
     25 int tri[12] ={0,1,3,9,27,81,243,729,2187,6561,19683,59049};
     26 int dig[59050][11];  //dig[state][k_dig]  状态state的第k位是多少
     27 int dp[59050][11];
     28 int d[15][15];
     29 int ans;
     30 int flag;
     31 
     32 void ini1()
     33 {
     34     int o,j,t;
     35     for(o=0;o<59049;o++){
     36         t=o;
     37         for(j=0;j<10;j++){
     38             dig[o][j]=t%3;
     39             t/=3;
     40         }
     41     }
     42 }
     43 
     44 void ini()
     45 {
     46     int a,b;
     47     int c;
     48     int i;
     49     ans=-1;
     50     memset(dp,-1,sizeof(dp));
     51     memset(d,-1,sizeof(d));
     52     while(m--){
     53         scanf("%d%d%d",&a,&b,&c);
     54         if(d[a][b]==-1){
     55             d[a][b]=c;
     56             d[b][a]=c;
     57         }
     58         else{
     59             d[a][b]=min(d[a][b],c);
     60             d[b][a]=min(d[b][a],c);
     61         }
     62     }
     63 
     64     for(i=1;i<=n;i++){
     65         dp[ tri[i] ][i-1]=0;
     66     }
     67 }
     68 
     69 void solve()
     70 {
     71     int o,j,te,k;
     72     for(o=1;o<tri[n+1];o++){
     73         flag=1;
     74         for(j=0;j<n;j++){
     75             if(dig[o][j]==0){
     76                 flag=0;continue;
     77             }
     78             te=o-tri[j+1];
     79             for(k=0;k<n;k++){
     80                 if(dig[te][k]==0) continue;
     81                 if(d[k+1][j+1]==-1) continue;
     82                 if(dp[te][k]==-1) continue;
     83                 if(dp[o][j]==-1){
     84                     dp[o][j]=dp[te][k]+d[k+1][j+1];
     85                 }
     86                 else{
     87                     dp[o][j]=min(dp[o][j],dp[te][k]+d[k+1][j+1]);
     88                 }
     89             }
     90         }
     91 
     92        // printf(" o=%d flag=%d
    ",o,flag);
     93         if(flag==0) continue;
     94         for(j=0;j<n;j++){
     95             if(dp[o][j]==-1) continue;
     96             if(ans==-1){
     97                 ans=dp[o][j];
     98             }
     99             else{
    100                 ans=min(ans,dp[o][j]);
    101             }
    102         }
    103 
    104     }
    105 }
    106 
    107 void out()
    108 {
    109     //for(int o=0;o<tri[n+1];o++){
    110     //    for(int j=0;j<n;j++) printf(" o=%d j=%d dp=%d
    ",o,j,dp[o][j]);
    111    // }
    112     printf("%d
    ",ans);
    113 }
    114 
    115 int main()
    116 {
    117     ini1();
    118     //freopen("data.in","r",stdin);
    119     //freopen("data.out","w",stdout);
    120     //scanf("%d",&T);
    121    // for(int cnt=1;cnt<=T;cnt++)
    122    // while(T--)
    123     while(scanf("%d%d",&n,&m)!=EOF)
    124     {
    125         ini();
    126         solve();
    127         out();
    128     }
    129     return 0;
    130 }
  • 相关阅读:
    VS2012 Unit Test(Void, Action, Func) —— 对无返回值、使用Action或Func作为参数、多重载的方法进行单元测试
    string中Insert与Format效率对比、String与List中Contains与IndexOf的效率对比
    VS2012 Unit Test —— 我对接口进行单元测试使用的技巧
    委托又给我惹麻烦了————记委托链的取消注册、获取返回值
    委托的N种写法,你喜欢哪种?
    VS2012 单元测试之泛型类(Generics Unit Test)
    Unity V3 初步使用 —— 为我的.NET项目从简单三层架构转到IOC做准备
    使用NuGet助您玩转代码生成数据————Entity Framework 之 Code First
    JqueryEasyUI浅谈---视频教程公布
    JqueryEasyUI浅谈本地化应用
  • 原文地址:https://www.cnblogs.com/njczy2010/p/3951638.html
Copyright © 2011-2022 走看看