poj3311 Hie with the Pie 旅行商问题(TSP)

题目链接 http://poj.org/problem?id=3311

Hie with the Pie

Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 5094   Accepted: 2716

Description

The Pizazz Pizzeria prides itself in delivering pizzas to its customers as fast as possible. Unfortunately, due to cutbacks, they can afford to hire only one driver to do the deliveries. He will wait for 1 or more (up to 10) orders to be processed before he starts any deliveries. Needless to say, he would like to take the shortest route in delivering these goodies and returning to the pizzeria, even if it means passing the same location(s) or the pizzeria more than once on the way. He has commissioned you to write a program to help him.

Input

Input will consist of multiple test cases. The first line will contain a single integer n indicating the number of orders to deliver, where 1 ≤ n ≤ 10. After this will be n + 1 lines each containing n + 1 integers indicating the times to travel between the pizzeria (numbered 0) and the nlocations (numbers 1 to n). The jth value on the ith line indicates the time to go directly from location i to location j without visiting any other locations along the way. Note that there may be quicker ways to go from i to j via other locations, due to different speed limits, traffic lights, etc. Also, the time values may not be symmetric, i.e., the time to go directly from location i to j may not be the same as the time to go directly from location j to i. An input value of n = 0 will terminate input.

Output

For each test case, you should output a single number indicating the minimum time to deliver all of the pizzas and return to the pizzeria.

Sample Input

3
0 1 10 10
1 0 1 2
10 1 0 10
10 2 10 0
0

Sample Output

8

Source

旅行商问题(Traveling Salesman Problem,TSP)又译为旅行推销员问题货郎担问题,简称为TSP问题,是最基本的路线问题,该问题是在寻求单一旅行者由起点出发,通过所有给定的需求点之后,最后再回到原点的最小路径成本。

题意:一个人运送披萨,从披萨店出发,需要运送给每个订购的客户,再回到披萨店,求所花的多少时间。(每个点可以重复走)

题目第一行给出一个n,表示有几个地方要运送,接下来是一个矩阵 a[i][j]表示从i到j需要花的时间。0表示披萨店。,因为可以重复走,所以先用弗洛伊德算法求一次最短路。

分析:之前没有做过旅行商问题,第一想法也是状压DP(这里n最大=10,其实也可以枚举),但是一开始没想好怎么表示状态。只设了dp[i]表示状态。

事实上应该设dp[i][j]表示状态为i时,终点为j的最小花的时间。

这样求解回到原点所花的时候就是求min(dp[((1<<n)-1][1]+a[1][0], dp[((1<<n)-1][2]+a[2][0] +....+dp[((1<<n)-1][n]+a[n][0] )

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 #include <string>
 5 #include <algorithm>
 6 using namespace std;
 7 #define INF 0x3f3f3f
 8 int n;
 9 int mp[11][11];
10 int dp[1<<11][11];
11 int main(){
12     while(scanf("%d", &n) && n){
13         for(int i = 0; i <= n; i++){
14             for(int j = 0; j <= n; j++){
15                 scanf("%d", &mp[i][j]);
16             }
17         }
18         for(int i = 0; i <= n; i++){
19             for(int j = 0; j <= n; j++){
20                 for(int k = 0; k <= n; k++){
21                     if(mp[i][j] + mp[j][k] <= mp[i][k]) mp[i][k] = mp[i][j] + mp[j][k];
22                 }
23             }
24         } //floyed算法先预处理一遍。
25
26         for(int i = 0; i < (1<<n); i++){
27             for(int j = 0; j <= n; j++) dp[i][j] = -1;
28         }
29         dp[0][0] = 0;
30         for(int pos = 1; pos <= n; pos++){
31             dp[1<<(pos-1)][pos] = mp[0][pos];
32         }
33
34
35         for(int i = 0; i < (1<<n); i++){
36             for(int j = 0; j <= n; j++){
37                 if(dp[i][j] != -1){ //这种状态可以达到
38                     for(int k = 0; k <= n; k++){
39                         if(( (1<<(k-1))&i) != 0) continue;  //如果这个点已经经过了
40                         if(dp[i|(1<<(k-1))][k] == -1) dp[i|(1<<(k-1))][k] = dp[i][j] + mp[j][k];
41                         else if(dp[i|(1<<(k-1))][k] >= dp[i][j] + mp[j][k]) dp[i|(1<<(k-1))][k]= dp[i][j] + mp[j][k];
42                     }
43                 }
44             }
45         }
46         int Min = INF;
47         for(int i = 1; i <= n; i++){
48             if( dp[(1<<n)-1][i] + mp[i][0] <= Min) Min =  dp[(1<<n)-1][i] + mp[i][0];
49         }
50         printf("%d\n",Min);
51     }
52
53     return 0;
54 }
时间: 2024-10-26 00:32:36

poj3311 Hie with the Pie 旅行商问题(TSP)的相关文章

poj3311(Hie with the Pie)状压dp

题目链接:http://poj.org/problem?id=3311 解法:标准的状压dp类型,先floyd获得两两之间最短距离.然后dp[i][j]表示剩下集合i没走,已经走到j的最短距离: 代码: /****************************************************** * @author:xiefubao *******************************************************/ #pragma comment(

状压DP Poj3311 Hie with the Pie

本人水平有限,题解不到为处,请多多谅解 本蒟蒻谢谢大家观看 题目: Problem C: Poj3311 Hie with the Pie Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 58  Solved: 29[Submit][Status][Web Board] Description The Pizazz Pizzeria prides itself in delivering pizzas to its customers as fast

POJ3311——Hie with the Pie

Hie with the Pie Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4646   Accepted: 2457 Description The Pizazz Pizzeria prides itself in delivering pizzas to its customers as fast as possible. Unfortunately, due to cutbacks, they can affo

POJ3311 Hie with the Pie

Hie with the Pie Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 7624   Accepted: 4106 Description The Pizazz Pizzeria prides itself in delivering pizzas to its customers as fast as possible. Unfortunately, due to cutbacks, they can affo

[POJ 3311]Hie with the Pie——谈论TSP难题DP解决方法

主题连接:  id=3311">http://poj.org/problem?id=3311 题目大意:有n+1个点,给出点0~n的每两个点之间的距离,求这个图上TSP问题的最小解 思路:用二进制数来表示訪问过的城市集合.f[{S}][j]=已经訪问过的城市集合为S,訪问了j个城市.所需的最少花费. 这里提一下二进制数表示集合的方法(这里最好还是设集合中最多有n个元素): 假设集合S中最多会出现n个元素,则用长度为n的二进制数来表示集合S,每一位代表一个元素.该位为0表示该元素在集合S

poj3311 Hie with the Pie,状态压缩

题目链接:http://poj.org/problem?id=3311 Floyd + 状态压缩DP 题意是有N个城市(1~N)和一个PIZZA店(0),要求一条回路,从0出发,又回到0,而且距离最小. 状态:dp[S][v]表示从v出发访问剩余的所有顶点(集合S),最终回到顶点0的路径的权重总和最小值. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; cons

POJ 3311 Hie with the Pie(TSP问题 状压DP)

Description The Pizazz Pizzeria prides itself in delivering pizzas to its customers as fast as possible. Unfortunately, due to cutbacks, they can afford to hire only one driver to do the deliveries. He will wait for 1 or more (up to 10) orders to be

Hie with the Pie(poj3311)

题目链接:http://poj.org/problem?id=3311 学习博客:https://blog.csdn.net/u013480600/article/details/19692985 Hie with the Pie Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 9954   Accepted: 5368 Description The Pizazz Pizzeria prides itself in de

POJ 3311 Hie with the Pie TSP+Floyd

保证每个点访问过一次就行,然后会到原点. 这种情况可以先做一边floyd,然后跑tsp就好. #include <cstdio> #include <cstring> #include <iostream> #include <map> #include <set> #include <vector> #include <string> #include <queue> #include <deque&g