zoukankan      html  css  js  c++  java
  • hdu--3001--类似旅行商<tsp>

    里面包含了很多内容的一道题 可以学到很多

    题意 很简单 就是一个人 要绕城市一圈 不必回到起点 但是每个城市都要经过 并且最多每个重复走2次

    注意 城市数量是 <=10的  如果 你以前就遇到过 类似的题 肯定能很快反应过来 状压dp 在某一维开个3维数组 0 1 2分别城市在该状态下经过某城市的次数为多少

    所以 就是个 三进制的压缩  蛮好的 以前只听过二进制 我孤陋寡闻了 =_=

    dp转移方程很简单 主要是 枚举状态的时候 各种细节要注意

    dp[ state+three[j] ][j] = min( dp[ state+three[j] ][j] , dp[ state ][i] + mp[i][j] );

    因为 城市个数实在是太水了 就用最简单的 二维矩阵存储吧 但会有重边 需要更新取最小值

    for( int i = 0 ; i<n ; i++ )
    {
        dp[ three[i] ][i] = 0;
    }

    这是个很重要的初始化 因为 我们没有固定从哪个点出发 那就表示 任意一点都可以当做起点

     1 #include <iostream>
     2 #include <cstring>
     3 #include <algorithm>
     4 using namespace std;
     5 
     6 int n;
     7 const int inf = 0X3f3f3f;    
     8 const int v = 60000;
     9 const int size = 11;
    10 int dp[v][size] , vis[v][size];
    11 int mp[size][size];
    12 int three[size];
    13 
    14 void init( )
    15 {
    16     int num;
    17     three[0] = 1;
    18     for( int i = 1 ; i<size ; i++ )
    19     {
    20         three[i] = three[i-1] * 3;
    21     }
    22     for( int i = 1 ; i<three[size-1] ; i++ )
    23     {
    24         num = i;
    25         for( int j = 0 ; j<size-1 ; j++ )
    26         {
    27             vis[i][j] = num % 3;
    28             num /= 3;
    29         }
    30     }
    31 }
    32 
    33 int solve( )
    34 {
    35     bool flag;
    36     int ans = inf;
    37     for( int state = 1 ; state<three[n] ; state++ )
    38     {
    39         flag = true;
    40         for( int i = 0 ; i<=n-1 ; i++ )
    41         {
    42             if( !vis[state][i] )
    43                 flag = false;
    44             if( dp[state][i] == inf )
    45                 continue;
    46             for( int j = 0 ; j<=n-1 ; j++ )
    47             {
    48                 if( i==j || mp[i][j] == inf || vis[state][j]>=2 )
    49                     continue;
    50                 dp[ state+three[j] ][j] = min( dp[ state+three[j] ][j] , dp[ state ][i] + mp[i][j] );
    51             }
    52         }
    53         if( flag )
    54         {
    55             for( int i = 0 ; i<=n-1 ; i++ )
    56             {
    57                 ans = min( ans , dp[state][i] );
    58             }
    59         }
    60     }
    61     return ans;
    62 }
    63 
    64 int main()
    65 {
    66     cin.sync_with_stdio(false);
    67     int m , a , b , c;
    68     int ans;
    69     init( );
    70     while( cin >> n >> m )
    71     {
    72         memset( dp , inf , sizeof(dp) );
    73         memset( mp , inf , sizeof(mp) );
    74         for( int i = 0 ; i<n ; i++ )
    75         {
    76             dp[ three[i] ][i] = 0;
    77         }
    78         while( m-- )
    79         {
    80             cin >> a >> b >> c;
    81             -- a;
    82             -- b;
    83             mp[a][b] = mp[b][a] = min( mp[a][b] , c );
    84         }
    85         ans = solve( );
    86         if( ans == inf )
    87             cout << -1 << endl;
    88         else
    89             cout << ans << endl;
    90     }
    91     return 0;
    92 }
    View Code


    today:

      忍受某段时光

      然后会被自己感动

    just follow your heart
  • 相关阅读:
    php 验证码
    扫描登录
    正则表达式
    liunx 搭建svn
    jq
    spl_autoload_register()函数
    php函数操作文件
    配置nginx支持TP框架
    Object-c 访问控制
    Obiective
  • 原文地址:https://www.cnblogs.com/radical/p/4096041.html
Copyright © 2011-2022 走看看