• hdu 3001(状压dp, 3进制)


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

    由于本题中一个点最多能够访问2次,由此可以联想到3进制;

    visited[i][j]表示在状态i下在点j已经做过的次数,dp[i][j]表示在状态i下到达点j走过的最小的路程,于是我们可以通过预处理得到visited[i][j]数组,然后就是一般的状态转移。

     1 /*************************************************************************
     2     > File Name: hdu3001.cpp
     3     > Author: syhjh
     4     > Created Time: 2014年03月09日 星期日 14时50分17秒
     5  ************************************************************************/
     6 #include <iostream>
     7 #include <cstdio>
     8 #include <cstring>
     9 #include <algorithm>
    10 using namespace std;
    11 
    12 const int inf = 0x3f3f3f3f;
    13 template < class T > inline T getMIN(const T &a, const T &b)
    14 {
    15     return a < b ? a : b;
    16 }
    17 
    18 int N, M;
    19 int dist[12][12];
    20 int State[12];
    21 int dp[60000][12];  //当前状态下在某个点的值
    22 int visited[60000][12]; //当前状态i下在点j已经走过的次数
    23 
    24 void Init()
    25 {
    26     State[0] = 1;
    27     for (int i = 1; i <= 10; i++) {
    28         State[i] = State[i - 1] * 3;
    29     }
    30     for (int s = 0; s <= State[10]; s++) {
    31         int x = s;
    32         for (int i = 0; i <= 10; i++) {
    33             visited[s][i] = x % 3;
    34             x /= 3;
    35         }
    36     }
    37 }
    38 
    39 int getDP()
    40 {
    41     int ans = inf;
    42     memset(dp, 0x3f, sizeof(dp));
    43     for (int i = 0; i < N; i++) dp[State[i]][i] = 0;
    44     for (int s = 0; s < State[N]; s++) {
    45         int flag = 1; //用于标记是否所有的点都已经走过
    46         for (int i = 0; i < N; i++) {
    47             if (visited[s][i] == 0) flag = 0;
    48             if (dp[s][i] == inf) continue;
    49             for (int j = 0; j < N; j++) if (j != i) {
    50                 if (visited[s][j] >= 2 || dist[i][j] == inf) continue;
    51                 dp[s + State[j]][j] = getMIN(dp[s + State[j]][j], dp[s][i] + dist[i][j]);
    52             }
    53         }
    54         if (flag) {
    55             for (int i = 0; i < N; i++) {
    56                 ans = getMIN(ans, dp[s][i]);
    57             }
    58         }
    59     }
    60     if (ans == inf) ans = -1;
    61     return ans;
    62 }
    63 
    64 
    65 int main()
    66 {
    67     Init();
    68     while (cin >> N >> M) {
    69         memset(dist, 0x3f, sizeof(dist));
    70         while (M--) {
    71             int u, v, w;
    72             cin >> u >> v >> w;
    73             u--, v--;
    74             dist[u][v] = dist[v][u] = getMIN(dist[u][v], w);
    75         }
    76         cout << getDP() << endl;
    77     }
    78     return 0;
    79 }
    View Code
  • 相关阅读:
    在tmux中如何复制文本并粘贴到某处?
    linux下的用户密码文件/etc/shadow
    linux下openssl命令解析
    第 27 章 CSS 传统布局[下]
    第 27 章 CSS 传统布局[上]
    第 26 章 CSS3 动画效果
    第 25 章 CSS3 过渡效果
    第 24 章 CSS3 变形效果[下]
    第 23 章 CSS3 边框图片效果
    第 22 章 CSS3 渐变效果
  • 原文地址:https://www.cnblogs.com/wally/p/3590138.html
Copyright © 2020-2023  润新知