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
  • 相关阅读:
    leetcode 122. Best Time to Buy and Sell Stock II
    leetcode 121. Best Time to Buy and Sell Stock
    python 集合(set)和字典(dictionary)的用法解析
    leetcode 53. Maximum Subarray
    leetcode 202. Happy Number
    leetcode 136.Single Number
    leetcode 703. Kth Largest Element in a Stream & c++ priority_queue & minHeap/maxHeap
    [leetcode]1379. Find a Corresponding Node of a Binary Tree in a Clone of That Tree
    正则表达式
    十种排序算法
  • 原文地址:https://www.cnblogs.com/radical/p/4096041.html
Copyright © 2011-2022 走看看