zoukankan      html  css  js  c++  java
  • HDU 3001 Travelling:TSP(旅行商)【节点最多经过2次】

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

    题意:

      有n个城市,m条双向道路,每条道路走一次需要花费路费v。你可以将任意一个城市作为起点出发,然后遍历每一个城市,并保证同一个城市最多经过2次。问你遍历这些城市的最小费用是多少。

     

    题解:

      传统的TSP问题中,每个城市只能经过一次,做法为三重for循环,分别枚举城市的state、现在所处位置i、下一步要到达的城市j。

      

      核心Code:

     1 memset(dp,-1,sizeof(dp));
     2 dp[1<<start][start]=0;
     3 for(int state=0;state<(1<<n);state++)
     4 {
     5     for(int i=0;i<n;i++)
     6     {
     7         if(dp[state][i]!=-1)
     8         {
     9             for(int j=0;j<n;j++)
    10             {
    11                 if(i!=j && !((state>>j)&1))
    12                 {
    13                     if(dp[state|(1<<j)][j]==-1 || dp[state|(1<<j)][j]>dp[state][i]+dis[i][j])
    14                     {
    15                         dp[state|(1<<j)][j]=dp[state][i]+dis[i][j];
    16                     }
    17                 }
    18             }
    19         }
    20     }
    21 }

     

      在这道题中,与传统TSP的唯一区别是每个城市最多经过的次数由1次变为了2次。那么表示每座城市的状态state也应该相应改为用三进制数表示,每一位上的数字代表对应城市已经经过的次数。

      所以把所有的二进制改为三进制就好啦 ( ̄▽ ̄)~*

      注:不用对于每一个起点分别求一次dp,会T。。。在开始要把所有的dp[update(0, i)][i] = 0

     

    AC Code:

      1 #include <iostream>
      2 #include <stdio.h>
      3 #include <string.h>
      4 #include <queue>
      5 #define MAX_N 15
      6 #define MAX_S 60000
      7 #define INF 100000000
      8 
      9 using namespace std;
     10 
     11 const int POW[]={1,3,9,27,81,243,729,2187,6561,19683,59049,177147,531441,1594323,4782969};
     12 
     13 int n,m;
     14 int a,b,v;
     15 int ans;
     16 int dis[MAX_N][MAX_N];
     17 int dp[MAX_S][MAX_N];
     18 
     19 void init()
     20 {
     21     for(int i=0;i<n;i++)
     22     {
     23         for(int j=0;j<n;j++)
     24         {
     25             dis[i][j]=INF;
     26             if(i==j) dis[i][j]=0;
     27         }
     28     }
     29 }
     30 
     31 void read()
     32 {
     33     for(int i=0;i<m;i++)
     34     {
     35         cin>>a>>b>>v;
     36         dis[a-1][b-1]=min(dis[a-1][b-1],v);
     37         dis[b-1][a-1]=min(dis[b-1][a-1],v);
     38     }
     39 }
     40 
     41 int query(int a,int k)
     42 {
     43     return a/POW[k]%3;
     44 }
     45 
     46 int update(int a,int k)
     47 {
     48     return a+POW[k];
     49 }
     50 
     51 bool check(int state)
     52 {
     53     for(int i=0;i<n;i++)
     54     {
     55         if(query(state,i)==0) return false;
     56     }
     57     return true;
     58 }
     59 
     60 void solve()
     61 {
     62     ans=INF;
     63     memset(dp,-1,sizeof(dp));
     64     for(int i=0;i<n;i++)
     65     {
     66         dp[update(0,i)][i]=0;
     67     }
     68     for(int state=0;state<POW[n];state++)
     69     {
     70         for(int i=0;i<n;i++)
     71         {
     72             if(dp[state][i]!=-1)
     73             {
     74                 for(int j=0;j<n;j++)
     75                 {
     76                     if(i!=j && query(state,j)<2)
     77                     {
     78                         int nex=update(state,j);
     79                         if(dp[nex][j]==-1 || dp[nex][j]>dp[state][i]+dis[i][j])
     80                         {
     81                             dp[nex][j]=dp[state][i]+dis[i][j];
     82                         }
     83                     }
     84                 }
     85                 if(check(state)) ans=min(ans,dp[state][i]);
     86             }
     87         }
     88     }
     89 }
     90 
     91 void print()
     92 {
     93     if(ans==INF) cout<<-1<<endl;
     94     else cout<<ans<<endl;
     95 }
     96 
     97 int main()
     98 {
     99     while(cin>>n>>m)
    100     {
    101         init();
    102         read();
    103         solve();
    104         print();
    105     }
    106 }

     

  • 相关阅读:
    CA证书扫盲,https讲解。
    关于jquery的入门,简单的封装。
    anglar JS使用两层ng-repeat嵌套使用,分辨$index
    JS中=>,>>>是什么意思
    撰写html标签的快捷方式2
    CSS 中伪类的顺序
    撰写html标签的快捷方式1
    文字换行显示
    input 控件监听回车确认按钮。
    git常用命令整理
  • 原文地址:https://www.cnblogs.com/Leohh/p/7366912.html
Copyright © 2011-2022 走看看