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]数组,然后就是一般的状态转移。

hdu 3001(状压dp, 3进制)
 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

 

你可能感兴趣的:(HDU)