poj 3311 Hie with the Pie (TSP问题)
| Time Limit: 2000MS | Memory Limit: 65536K | |
| Total Submissions: 4491 | Accepted: 2376 |
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 n locations (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
题意:从起点0開始。遍历全部的点并回到起点的最短距离。每一个点能够经过多次。
ans1:
DP+状态压缩:dp[state][i]表示起点到达i点,状态为state的最短距离。
dp[state][i] =min{dp[state][i],dp[state'][j]+dis[j][i]} dis[j][i]为j到i的最短距离;
</pre><pre name="code" class="cpp">#include<stdio.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<queue>
using namespace std;
#define ll __int64
#define mem(a,t) memset(a,t,sizeof(a))
#define N 12 const int inf=0x3fffffff;
int g[N][N];
int dp[1<<11][N];//dp[state][i]表示在当前状态下,从起点0到达i点的最短距离
void floyd(int n)
{
int i,j,k;
for(k=0; k<=n; k++) //Floyd求最短路
for(i=0; i<=n; i++)
for(j=0; j<=n; j++)
g[i][j]=min(g[i][j],g[i][k]+g[k][j]);
}
int main()
{
//freopen("in.txt","r",stdin);
int n,i,j,k,s;
while(scanf("%d",&n),n)
{
for(i=0; i<=n; i++)
for(j=0; j<=n; j++)
scanf("%d",&g[i][j]);
floyd(n);
for(i=0;i<(1<<(n+1));i++)
for(j=0;j<=n;j++)
dp[i][j]=inf;
dp[0][0]=0;
for(s=0; s<(1<<(n+1)); s++) //枚举每一个状态
{
for(i=0; i<=n; i++) //枚举中间点。看能否使距离变短
{
if(!(s&(1<<i)))
continue;
for(k=0; k<=n; k++)
dp[s][i]=min(dp[s][i],dp[s^(1<<i)][k]+g[k][i]);
}
}
printf("%d\n",dp[(1<<(n+1))-1][0]);
}
return 0;
}
ans2:
bfs+状态压缩:先用Floyd求出随意两点之间的最短路。然后。能够用广搜求得答案,搜索中的每一个点第一次到达用二进制位进行标记。
#include<iostream>
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<queue>
using namespace std;
#define N 12
const int inf=0x3fffffff;
struct node
{
int x,s,t; //位置、状态、时间
int cnt; //訪问地点数目
friend bool operator<(node a,node b)
{
return a.t>b.t;
}
};
int mark[N][1030];
int g[N][N];
int n,ans;
void Floyd()
{
int i,j,k;
for(k=0;k<=n;k++)
{
for(i=0;i<=n;i++)
{
for(j=0;j<=n;j++)
{
g[i][j]=min(g[i][j],g[i][k]+g[k][j]);
}
}
}
}
void bfs(int u)
{
int i;
priority_queue<node >q;
node cur,next;
cur.x=u;
cur.t=cur.s=cur.cnt=0;
q.push(cur);
mark[u][0]=0;
q.push(cur);
while(!q.empty())
{
cur=q.top();
q.pop();
for(i=0;i<=n;i++)
{
next.s=cur.s;
next.t=cur.t;
next.cnt=cur.cnt;
next.x=i;
next.t+=g[cur.x][i];
if(i&&(next.s&(1<<(i-1)))==0)
{
next.s|=(1<<(i-1));
next.cnt++;
}
if(next.t<mark[i][next.s])
{
mark[i][next.s]=next.t;
if(next.cnt==n)
{
ans=min(ans,next.t+g[i][0]);
continue;
}
q.push(next);
}
}
}
}
int main()
{
int i,j;
while(scanf("%d",&n),n)
{
for(i=0;i<=n;i++)
{
for(j=0;j<=n;j++)
{
scanf("%d",&g[i][j]);
}
}
Floyd();
for(i=0;i<=n;i++)
{
for(j=0;j<(1<<n);j++)
mark[i][j]=inf;
}
ans=inf;
bfs(0);
printf("%d\n",ans);
}
return 0;
}
poj 3311 Hie with the Pie (TSP问题)的更多相关文章
- poj 3311 Hie with the Pie
floyd,旅游问题每个点都要到,可重复,最后回来,dp http://poj.org/problem?id=3311 Hie with the Pie Time Limit: 2000MS Me ...
- poj 3311 Hie with the Pie dp+状压
Hie with the Pie Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 4671 Accepted: 2471 ...
- POJ 3311 Hie with the Pie 最短路+状压DP
Hie with the Pie Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 11243 Accepted: 5963 ...
- [POJ 3311]Hie with the Pie——谈论TSP难题DP解决方法
主题连接: id=3311">http://poj.org/problem?id=3311 题目大意:有n+1个点,给出点0~n的每两个点之间的距离,求这个图上TSP问题的最小解 ...
- POJ 3311 Hie with the Pie:TSP(旅行商)【节点可多次经过】
题目链接:http://poj.org/problem?id=3311 题意: 你在0号点(pizza店),要往1到n号节点送pizza. 每个节点可以重复经过. 给你一个(n+1)*(n+1)的邻接 ...
- poj 3311 Hie with the Pie (状压dp) (Tsp问题)
这道题就是Tsp问题,稍微加了些改变 注意以下问题 (1)每个点可以经过多次,这里就可以用弗洛伊德初始化最短距离 (2)在循环中集合可以用S表示更清晰一些 (3)第一维为状态,第二维为在哪个点,不要写 ...
- POJ 3311 Hie with the Pie 兼 Codevs 2800 送外卖(动态规划->TSP问题)
Description The Pizazz Pizzeria prides itself in delivering pizzas to its customers as fast as possi ...
- POJ 3311 Hie with the Pie(状压DP + Floyd)
题目链接:http://poj.org/problem?id=3311 Description The Pizazz Pizzeria prides itself in delivering pizz ...
- POJ 3311 Hie with the Pie(DP状态压缩+最短路径)
题目链接:http://poj.org/problem?id=3311 题目大意:一个送披萨的,每次送外卖不超过10个地方,给你这些地方之间的时间,求送完外卖回到店里的总时间最小. Sample In ...
随机推荐
- 逆向学习XXclient怎样仅仅执行一个实例
个人觉得学习分两种, 一种是当面请教和直接从书本网络中的资料学习. 其二就是看着令你惊叹的作品-顿悟. 什么?顿悟不了?那我们就一起来逆向学习吧!差点忘了,我并不打算提供Demo,这并不重要,难道你打 ...
- Chisel Tutorial(一)——Chisel介绍
Chisel是由伯克利大学公布的一种开源硬件构建语言,建立在Scala语言之上,是Scala特定领域语言的一个应用,具有高度參数化的生成器(highly parameterized generator ...
- Log使用
学习参考:http://blog.csdn.net/hu_shengyang/article/details/6754031 log4j三种主要组件: logger记录对象 appender输出对象 ...
- js 数组克隆
在JS中,对于对象类型的变量的引用是通过类似C之类的"指针"的方式来操作的,及假设多个变量引用同一个对象,则随意一个变量对对象的操作都会影响到其他的变量. 这个可能不是非常明确,以 ...
- 开源APM应用性能管理工具调研
近期在设计一个DevOps平台.希望整合一个APM工具进来,由于APM既可用于性能測试也可用于运维性能监控,是典型的Dev+Ops产品. 商业的APM工具国内外已经有不少成熟产品了,而开源的好像不多见 ...
- Linux平台Oracle多个实例启动
如何在Linux系统中启动多个Oracle实例?相信很多Oracle的初学者都会碰到这一类问题,下面我简单介绍一下. 1.切换Oracle用户: # su oracle 2.切换到Oracle目录下: ...
- 【BZOJ 2463】 谁能赢呢?
[题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=2463 [算法] n为偶数时必胜,否则必败 [代码] #include<bits ...
- 两个TableView产生联动的一中方法
如何使用两个TableView产生联动:将两个tableView的滚动事件禁止掉,最外层scrollView滚动时将两个TableView跟着滚动,并且更改contentOffset,这样产生效果滚动 ...
- 数据库 The Network Adapter could not establish the connection解决方案
连接数据库 注意 url ip地址换的时候 oracle 里的listener.ora thnsnames.ora也要随之变化 重启数据库 不然可能会报出 java.sql.SQLException: ...
- js 手机号码简单正则校验
现在手机号码的号段有如下几种,包括17年新发出的三个(166,199,198)号段. 在一些项目注册登录或者其他中,涉及到手机号进行一个简单的有效验证,在前端先进行一个简单的检验: 判断字符串是否符合 ...