HDU 3001 Travelling

Travelling

Time Limit: 3000ms

Memory Limit: 32768KB

This problem will be judged on HDU. Original ID: 3001
64-bit integer IO format: %I64d      Java class name: Main

After coding so many days,Mr Acmer wants to have a good rest.So travelling is the best choice!He has decided to visit n cities(he insists on seeing all the cities!And he does not mind which city being his start station because superman can bring him to any city at first but only once.), and of course there are m roads here,following a fee as usual.But Mr Acmer gets bored so easily that he doesn‘t want to visit a city more than twice!And he is so mean that he wants to minimize the total fee!He is lazy you see.So he turns to you for help.

Input

There are several test cases,the first line is two intergers n(1<=n<=10) and m,which means he needs to visit n cities and there are m roads he can choose,then m lines follow,each line will include three intergers a,b and c(1<=a,b<=n),means there is a road between a and b and the cost is of course c.Input to the End Of File.

Output

Output the minimum fee that he should pay,or -1 if he can‘t find such a route.

Sample Input

2 1
1 2 100
3 2
1 2 40
2 3 50
3 3
1 2 3
1 3 4
2 3 10

Sample Output

100
90
7 

Source

2009 Multi-University Training Contest 11 - Host by HRBEU

解题:状压dp...

s[i][j]表示在状态i下,city j被访问了 多少次。

只有s[i][j]中的所有j都大于0 即至少访问过一次,才能把此态视为终态。否则,不能视为终态。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <algorithm>
 6 #include <climits>
 7 #include <vector>
 8 #include <queue>
 9 #include <cstdlib>
10 #include <string>
11 #include <set>
12 #include <stack>
13 #define LL long long
14 #define pii pair<int,int>
15 #define INF 0x3f3f3f3f
16 using namespace std;
17 int tri[] = {0,1,3,9,27,81,243,729,2187,6561,19683,59049};
18 int e[12][12],dp[59049][12],s[59049][12] = {0};
19 int main() {
20     int n,m,x,y,z;
21     for(int i = 0; i < 59049; i++) {
22         int tmp = i;
23         for(int k = 1; k <= 10; k++) {
24             s[i][k] = tmp%3;
25             tmp /= 3;
26         }
27     }
28     while(~scanf("%d %d",&n,&m)) {
29         for(int i = 1; i <= n; i++)
30             for(int j = 1; j <= n; j++) e[i][j] = INF;
31         for(int i = 0; i < m; i++) {
32             scanf("%d %d %d",&x,&y,&z);
33             if(e[x][y] > z) e[x][y] = e[y][x] = z;
34         }
35         for(int i = 0; i < tri[n+1]; i++)
36             for(int j = 1; j <= 10; j++) dp[i][j] = INF;
37         for(int i = 0; i <= 10; i++) dp[tri[i]][i] = 0;
38         int ans = INF;
39         for(int i = 0; i < tri[n+1]; i++) {
40             bool flag = true;
41             for(int j = 1; j <= n; j++) {
42                 if(s[i][j] == 0) flag = false;
43                 for(int k = 1; k <= n; k++){
44                     if(j == k || e[j][k] == INF || s[i][k] == 2) continue;
45                     int ns = i + tri[k];
46                     dp[ns][k] = min(dp[ns][k],dp[i][j] + e[j][k]);
47                 }
48             }
49             for(int k = 1; flag && k <= n; k++)
50                 ans = min(ans,dp[i][k]);
51         }
52         ans == INF?puts("-1"):printf("%d\n",ans);
53     }
54     return 0;
55 }

时间: 2024-11-05 11:55:51

HDU 3001 Travelling的相关文章

HDU 3001 Travelling (三进制状态压缩 DP)

题意:有 n 个city,可以选择任一城市作为起点,每个城市不能访问超过2次, 城市之间有权值,问访问全部n个城市需要的最小权值. 思路:因为每个城市可以访问最多两次,所以用三进制表示访问的状态. 详细见代码注释!!!! #include<cstdio> #include<stdlib.h> #include<string.h> #include<string> #include<map> #include<cmath> #inclu

hdu 3001 Travelling TSP变形 三进制状压dp

// hdu 3001 TSP问题的变形 // 这次到每个点最多两次,所以可以用三进制的类推 // dp[S][u]表示当前在u点访问状态为S时所得到的最小的开销 // 采用刷表法,即用当前的状态推出它所能转移的状态 // dp[S][u] 可以到达的状态为dp[S+state[v]][v](dist[u][v]!=inf) // dp[S+state[v]][v] = max(dp[S+state[v]][v],dp[S][u]+dist[u][v]); // 其中每个点最多访问2次 // 技

HDU 3001 Travelling 状压DP

链接:http://acm.hdu.edu.cn/showproblem.php?pid=3001 题意:还是环游地图的问题,只不过这回旅行者对自己有着严格的要求,地图上每个点的经过次数不能超过两次. 思路:依然是状压DP问题,根上一道很像,只不过这次对于每个点来说有三种状态,分别是未经过,经过一次,经过两次.所以要用三进制的数来进行状态压缩,这个关键点想明白了其他的和上一道基本一样了.对于我来说需要注意的是:能够到达某一个点经过了两次的状态的前一个状态是这个点已经经过了一次的状态,而不是从来未

HDU 3001 Travelling:TSP(旅行商)

题目链接: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

HDU 3001 Travelling(状态压缩DP+三进制)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3001 题目大意:有n个城市,m条路,每条路都有一定的花费,可以从任意城市出发,每个城市不能经过两次以上,要求经过所有城市并且花费最少,求出最小花费. 解题思路:三进制的状态压缩DP,跟二进制还是有一点不一样的,因为三进制没有直接的位运算,还要自己先做处理利用num[i][j]记录数字i各位的三进制表示方便计算,其他的就跟二进制状态压缩没有太大区别了.还有注意: ①开始要将n个起点初始化,dp[bit

hdu 3001 Travelling (bfs+状态压缩)

Travelling Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3905    Accepted Submission(s): 1234 Problem Description After coding so many days,Mr Acmer wants to have a good rest.So travelling is

状压DP [HDU 3001] Travelling

Travelling Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 4166    Accepted Submission(s): 1339 Problem Description After coding so many days,Mr Acmer wants to have a good rest.So travelling is

hdu 3001 Travelling (TSP问题 )

Travelling Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3905    Accepted Submission(s): 1234 Problem Description After coding so many days,Mr Acmer wants to have a good rest.So travelling is

hdu 3001 Travelling(状态压缩 三进制)

Travelling Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 6600    Accepted Submission(s): 2144 Problem Description After coding so many days,Mr Acmer wants to have a good rest.So travelling is