主题连接:



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中不存在,为1表示该元素在集合S中存在

位数 4 3 2 1

S     1 0 1 1

这个集合S里有元素1、2、4

以下是二进制数表示几种集合运算的方法

1、集合S的全集U=(1<<n)-1

2、检查集合S中是否含元素i   S&(1<<(i-1))   (返回0表示不存在。返回1表示存在)

3、从集合S中去除元素i S^(1<<(i-1))

以下是本题的思路:

首先对整个图跑一次Floyd多源最短路。得到两两点之间的最短距离,然后用DP求解,f[{S}][j]=已经訪问过的城市集合为S。訪问了j个城市,所需的最少花费。

f[S][i]=min{f[S-{j}][j]+dist[j][i]}

最后得到的答案ans=min(f[全集][i]+dist[i][0])

代码:

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm> #define MAXN 15
#define MAXM 1<<15
#define INF 0x3f3f3f3f using namespace std; int f[MAXM][MAXN]; //f[{S}][j]=已经訪问过的城市集合为S。訪问了j个城市,所需的最少花费
int dist[MAXN][MAXN]; //点与点之间的距离
int n; int min(int a,int b)
{
if(a<b) return a;
return b;
} void Floyd()
{
for(int k=0;k<=n;k++)
for(int i=0;i<=n;i++)
for(int j=0;j<=n;j++)
dist[i][j]=min(dist[i][j],dist[i][k]+dist[k][j]);
} int TSP() //DP求TSP
{
memset(f,0x7f,sizeof(f));
for(int s=0;s<(1<<n);s++) //枚举訪问城市集合S,全集为(1<<n)-1
for(int i=1;i<=n;i++) //枚举近期訪问过的城市i
if(s&(1<<(i-1))) //city(i)∈S
{
if(s==(1<<(i-1))) //{city(i)}==S
f[s][i]=dist[0][i];
else
{
for(int j=1;j<=n;j++) //枚举上一次訪问的城市j
if((s&(1<<(j-1)))&&i!=j) //城市j不和i同样
f[s][i]=min(f[s][i],f[s^(1<<(i-1))][j]+dist[j][i]); //Cs {city(J)}=s^(1<<(i-1))
}
}
int ans=INF;
for(int i=1;i<=n;i++)
ans=min(ans,f[(1<<n)-1][i]+dist[i][0]);
return ans;
} int main()
{
while(scanf("%d",&n)&&n)
{
memset(dist,0,sizeof(dist));
for(int i=0;i<=n;i++)
for(int j=0;j<=n;j++)
scanf("%d",&dist[i][j]);
Floyd();
printf("%d\n",TSP());
}
return 0;
}

版权声明:本文博主原创文章,博客,未经同意不得转载。

[POJ 3311]Hie with the Pie——谈论TSP难题DP解决方法的更多相关文章

  1. POJ 3311 Hie with the Pie:TSP(旅行商)【节点可多次经过】

    题目链接:http://poj.org/problem?id=3311 题意: 你在0号点(pizza店),要往1到n号节点送pizza. 每个节点可以重复经过. 给你一个(n+1)*(n+1)的邻接 ...

  2. poj 3311 Hie with the Pie (状压dp) (Tsp问题)

    这道题就是Tsp问题,稍微加了些改变 注意以下问题 (1)每个点可以经过多次,这里就可以用弗洛伊德初始化最短距离 (2)在循环中集合可以用S表示更清晰一些 (3)第一维为状态,第二维为在哪个点,不要写 ...

  3. POJ 3311 Hie with the Pie(状压DP + Floyd)

    题目链接:http://poj.org/problem?id=3311 Description The Pizazz Pizzeria prides itself in delivering pizz ...

  4. POJ 3311 Hie with the Pie floyd+状压DP

    链接:http://poj.org/problem?id=3311 题意:有N个地点和一个出发点(N<=10),给出全部地点两两之间的距离,问从出发点出发,走遍全部地点再回到出发点的最短距离是多 ...

  5. POJ 3311 Hie with the Pie(Floyd+状态压缩DP)

    题是看了这位的博客之后理解的,只不过我是又加了点简单的注释. 链接:http://blog.csdn.net/chinaczy/article/details/5890768 我还加了一些注释代码,对 ...

  6. poj 3311 Hie with the Pie(状态压缩dp)

    Description The Pizazz Pizzeria prides itself or more (up to ) orders to be processed before he star ...

  7. POJ 3311 Hie with the Pie (状压DP)

    题意: 每个点都可以走多次的TSP问题:有n个点(n<=11),从点1出发,经过其他所有点至少1次,并回到原点1,使得路程最短是多少? 思路: 同HDU 5418 VICTOR AND WORL ...

  8. POJ 3311 Hie with the Pie 【状压DP】

    Description The Pizazz Pizzeria prides itself in delivering pizzas to its customers as fast as possi ...

  9. poj 3311 Hie with the Pie

    floyd,旅游问题每个点都要到,可重复,最后回来,dp http://poj.org/problem?id=3311 Hie with the Pie Time Limit: 2000MS   Me ...

随机推荐

  1. MyReport报表引擎2.1.0.0新功能

    支持简单的四则运算样例1:算总分,简单连加 样例2:算平均分.除非和加法混合(可以识别先乘除后加减,不支持小括号优先运算) 新增行号函数 直接生成行号 新增多种格式化设置修复数个已发现的Bug.优化代 ...

  2. 从jdbc到mybatis

    前面我已经写了几篇文章介绍mybatis的使用方法, 现准备从原理上分析mybatis, 本篇将会解说JDBC演变到mybatis的过程. JDBC查询 使用jdbc查询数据库一般有下面七个步骤: 1 ...

  3. DataGridView绑定数据源

    给DataGridView绑定数据源比較简单,方法主要有两种: 1.直接在控件属性中绑定数据源,这样的方法最简单,但它是直接连接数据库的,这样就和传DataTable的后果差点儿相同了,所以还是尽量避 ...

  4. Android - 用Fragments实现动态UI - 和其他Fragments通信

    为了重用Fragment UI组件,应该把每个都设计为它自有的模块组件并且有自己的布局和行为.一旦定义了这些可重用的Fragment,你可以把它们和一个activity关联然后和程序的逻辑一起实现上层 ...

  5. jwt (JSON Web Token)官方说明

    http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-32#appendix-A 相关文章 http://haomou.net/2014 ...

  6. GitLab 之 Linux十分钟快装(转)

    先把 Shell 命令贴出来,楼主以 CentOS release 6.5 (Final) 64位 为例: //配置系统防火墙,把HTTP和SSH端口开放. sudo yum install curl ...

  7. PKU A Simple Problem with Integers (段树更新间隔总和)

    意甲冠军:一个典型的段树C,Q问题,有n的数量a[i] (1~n),C, a, b,c在[a,b]加c Q a b 求[a,b]的和. #include<cstdio> #include& ...

  8. 纯洁CSS实现下拉菜单和下拉容器(纯洁CSS导航栏和导航下拉容器)

    虽然网上课程似即使案件大同小异,但我还是写,记笔记,也为您提供参考 我希望你能指导批评~~ 首先,我们必须列出ul li 开始我们的导航栏菜单也能说生产: 在下面的页面,我们先建XHTML结构体: & ...

  9. 创建高性能移动 web 站点【转载】

    如果你的网站3秒钟没有响应,人们就会失去兴趣了.为了满足响应快这个愿望,需要一个不同的方法在手机上进行分析,设计和测试. 这篇文章将会对Johan Johansson在2013年4月提出"  ...

  10. Android于JNI调用列出的程序

    1.安装和下载cygwin,下载Android NDK: 2.于ndk工程JNI接口设计: 3.采用C/C++实现本地方法. 4.JNI生成动态链接库.so档: 5.动态链接库副本javaprojec ...