问题来源:刘汝佳《算法竞赛入门经典--训练指南》 P61 问题9:

问题描述:有n(n<=15)个城市,两两之间均有道路直接相连,给出每两个城市i和j之间的道路长度L[i][j],求一条经过每个城市一次且仅一次,最后回到起点的路线,使得经过的道路总长度最短(城市编号为0~n-1)。

分析: 1.因为最后走的路线为一个环,可以设城市0为起点城市。

    2.将每个城市看作二进制的一个位(1代表有,0代表没有),则数k可以表示一些城市的集合(例如k=13,二进制表示为1101,表示城市0,2,3的集合),我们可以求得k<=2^15-1,令  aim=2^15-1;

    3.dp[k][j]表示经过了k集合中的所有城市并且以j城市为终点的路径的最小值

    则dp[k][j] = Min{dp[k][j],dp[k-j][i]+dis[i][j] | (0<=i<=n-1 && i属于集合k)};(其中k-j表示集合k中去掉数j后的集合(所以j应该是集合k中的元素)),

例题链接:http://acm.fzu.edu.cn/problem.php?pid=2186

例题: fzu 2186

Problem 2186 小明的迷宫

Accept: 88    Submit: 270
Time Limit: 1000 mSec    Memory Limit : 32768 KB

 Problem Description

小明误入迷宫,塞翁失马焉知非福,原来在迷宫中还藏着一些财宝,小明想获得所有的财宝并离开迷宫。因为小明还是学生,还有家庭作业要做,所以他想尽快获得所有财宝并离开迷宫。

 Input

有多组测试数据。

每组数据第一行给出两个正整数n,m(0<n,m<=100)。代表迷宫的长和宽。

接着n行,每行m个整数。正数代表财宝(财宝的个数不超过10);负数代表墙,无法通过;0代表通道。

每次移动到相邻的格子,所花费的时间是1秒。小明只能按上、下、左、右四个方向移动。

小明的初始位置是(1,1)。迷宫的出口也在(1,1)。

 Output

输出获得所有财宝并逃出迷宫所花费的最小时间,如果无法完成目标则输出-1。

 Sample Input

3 3
0 0 0
0 100 0
0 0 0
2 2
1 1
1 1

 Sample Output

4
4

 Source

FOJ有奖月赛-2015年03月

思路:先将出口和宝藏之间的距离全部通过DFS求出来(出口的地方需要特殊判断和处理),接下来就是裸的TSP问题dp+状压
 #include "stdio.h"
#include "string.h"
#include "queue"
using namespace std;
#define N 105
#define INF 0x3fffffff int m,n;
int map[N][N],mark[N][N];
int dis[][],flag[],dist[];
int dir[][] = {{-,},{,},{,-},{,}}; int dp[][],b[];
int inline Min(int a,int b){ return a<b?a:b; } struct Point
{
int x,y;
} point[]; struct node
{
int x,y;
int length;
}; void DFS(int start,int x,int y,int length)
{
int i,k;
int x1,y1;
queue<node> q;
node cur,next;
cur.x = x;
cur.y = y;
cur.length = ;
q.push(cur);
while(!q.empty())
{
cur = q.front();
q.pop();
for(i=; i<; i++)
{
next.x = x1 = cur.x+dir[i][];
next.y = y1 = cur.y+dir[i][];
next.length = cur.length+;
if(x1<= || x1>n || y1<= || y1>m || mark[x1][y1]!= || map[x1][y1]<)
continue;
if(map[x1][y1]>)
{
k = map[x1][y1];
dis[start][k] = dis[k][start] = next.length;
}
mark[x1][y1] = ;
q.push(next);
}
}
} int main()
{
int ans;
int i,j,k,num,l;
b[] = ;
for(i=; i<; i++) //b[i]存的2^i
b[i] = b[i-]*;
while(scanf("%d %d",&n,&m)!=EOF)
{
num = ;
for(i=; i<=n; ++i)
{
for(j=; j<=m; j++)
{
scanf("%d",&map[i][j]);
if(i== && j==&& map[i][j]>) num--;
if(map[i][j]>) map[i][j]= num++;
else if(map[i][j]<) map[i][j]=-;
}
}
if(map[][]<)
{
printf("-1\n");
continue;
}
map[][] = ;
for(i=; i<=n; ++i)
{
for(j=; j<=m; j++)
{
if(map[i][j]>)
{
k = map[i][j];
point[k].x = i, point[k].y = j;
} }
}
for(i=; i<num; i++)
{
for(j=; j<num; j++)
dis[i][j] = INF;
dis[i][i]= ;
}
for(i=; i<num; i++) //以每个点为起点广搜,求出任意两点间的最短距离
{
memset(mark,,sizeof(mark));
mark[point[i].x][point[i].y] = ;
DFS(i,point[i].x,point[i].y,);
}
num--; //宝藏编号为1~num
int tt = ;
for(i=; i<=num; i++)
{
if(dis[][i]==INF) //只要存在一个INF,表示至少有一个宝藏不可达,输出-1
tt = ;
}
if(tt==)
{
printf("-1\n");
continue;
}
int aim =b[num+]-;//y因为从2^1开始到2^num,则aim = 2^(num+1)-1-2^0
for(i=; i<=aim; i++)
{
for(j=; j<=num; j++)
dp[i][j] = INF;
}
dp[][] = ;
for(l=; l<=aim; l++) //一个集合l
{
for(i=; i<=num; i++)
{
for(j=; j<=num; j++)
{
if(i==j) continue;
if((b[i]&l)==) continue; //必须满足i 在集合l中,不满足,跳过,
if((b[j]&l)==) continue; //必须满足j不在集合l中,不满足,跳过,
if(dp[l][i]==INF) continue;
dp[l|b[j]][j]=Min(dp[l|b[j]][j],dp[l][i]+dis[i][j]);
}
}
}
ans = INF;
for(i=; i<=num; i++)
ans = Min(ans,dp[aim][i]+dis[i][]);
printf("%d\n",ans);
}
return ;
}

07_旅行商问题(TSP问题,货郎担问题,经典NPC难题)的更多相关文章

  1. 【智能算法】用模拟退火(SA, Simulated Annealing)算法解决旅行商问题 (TSP, Traveling Salesman Problem)

    喜欢的话可以扫码关注我们的公众号哦,更多精彩尽在微信公众号[程序猿声] 文章声明 此文章部分资料和代码整合自网上,来源太多已经无法查明出处,如侵犯您的权利,请联系我删除. 01 什么是旅行商问题(TS ...

  2. 遗传算法解决旅行商问题(TSP)

    这次的文章是以一份报告的形式贴上来,代码只是简单实现,难免有漏洞,比如循环输入的控制条件,说是要求输入1,只要输入非0就行.希望会帮到以后的同学(*^-^*) 一.问题描述 旅行商问题(Traveli ...

  3. 禁忌搜索算法TSA 旅行商问题TSP python

    import math import random import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot ...

  4. 三进制状态压缩DP(旅行商问题TSP)HDU3001

    http://acm.hdu.edu.cn/showproblem.php?pid=3001 Travelling Time Limit: 6000/3000 MS (Java/Others)     ...

  5. hdu 2224 双调欧几里得旅行商问题tsp

    /* 题意:平面上n个点,确定一条连接各点的最短闭合旅程且每个点仅用一次.这个解的一般形式为NP的(在多项式时间内可以求出) 建议通过只考虑双调旅程(bitonictour)来简化问题,这种旅程即为从 ...

  6. 回溯法 | 旅行商问题(TSP问题)

    学习链接: 回溯法解旅行商问题(TSP).贪心算法:旅行商问题(TSP) 今天早上做了无数个梦,然后被紧紧地吸附在床上.挣扎一番后爬起来,已经是9点了.然后我开始研究旅行商问题. 在一个无向图中找到一 ...

  7. 转载 什么是P问题、NP问题和NPC问题

    原文地址http://www.matrix67.com/blog/archives/105 这或许是众多OIer最大的误区之一.    你会经常看到网上出现“这怎么做,这不是NP问题吗”.“这个只有搜 ...

  8. P问题、NP问题、NPC问题、NP难问题的概念

    P问题.NP问题.NPC问题.NP难问题的概念 离入职尚有几天时间,闲来无事,将大家常见却又很容易搞糊涂的几个概念进行整理,希望对大家有所帮助.你会经常看到网上出现“这怎么做,这不是NP问题吗”.“这 ...

  9. P问题、NP问题和NPC问题

    P问题.NP问题和NPC问题 这或许是众多OIer最大的误区之一.    你会经常看到网上出现“这怎么做,这不是NP问题吗”.“这个只有搜了,这已经被证明是NP问题了”之类的话.你要知道,大多数人此时 ...

随机推荐

  1. ChartDirector应用笔记(二)

    关于Simple Bar Chart Simple bar chart是XYChart大类中的Bar chart类型中的最简单的例子.Bar chart的表现形式简单直观,在数据量较少.数据维度简单等 ...

  2. Oracle Fusion Applications (11.1.8) Media Pack and Oracle Application Development Framework 11g (11.1.1.7.2) for Microsoft Windows x64 (64-bit)

    Oracle Fusion Applications (11.1.8) Media Pack for Microsoft Windows x64 (64-bit) 重新搜索   常见问题    提示  ...

  3. ASP.NET MVC传送参数至服务端

    ASP.NET MVC传送参数至服务端,前端与服务端的写法,你可以参考与采用适合你的需求的.当你只传递一两个参数也许觉得没有什么,如果一个方法中带的参数多的话,可以考虑model,前端可以考虑对象进行 ...

  4. HTML5实现音频播放

    Web 上的音频 直到现在,仍然不存在一项旨在网页上播放音频的标准. 今天,大多数音频是通过插件(比如 Flash)来播放的.然而,并非所有浏览器都拥有同样的插件. HTML5 规定了一种通过 aud ...

  5. sql 添加修改说明

    --为字段a2添加描述信息 EXECUTE sp_addextendedproperty N'MS_Description', '性别', N'user', N'dbo', N'table', N'表 ...

  6. linux下安装或升级GCC4.8,以支持C++11标准

    C++11标准在2011年8月份获得一致通过,这是自1998年后C++语言第一次大修订,对C++语言进行了改进和扩充.随后各编译器厂商都各自实现或部分实现了C++中的特性. 如需查看各编译器对C++1 ...

  7. [Eclipse] - 解决导入flask模块出现的Unresolved Import flask问题

    http://www.cnblogs.com/mizhon/p/4242073.html [Eclipse] - 解决导入flask模块出现的Unresolved Import flask问题 最近想 ...

  8. [PHP] 实现路由映射到指定控制器

    自定义路由的功能,指定到pathinfo的url上,再次升级之前的脚本 SimpleLoader.php <?php class SimpleLoader{ public static func ...

  9. 利用多写Redis实现分布式锁原理与实现分析(转)

    利用多写Redis实现分布式锁原理与实现分析   一.关于分布式锁 关于分布式锁,可能绝大部分人都会或多或少涉及到. 我举二个例子:场景一:从前端界面发起一笔支付请求,如果前端没有做防重处理,那么可能 ...

  10. j2ee log4j集中式日志解决方案logpool-v0.4发布说明

    logpool v0.4发布说明: 1.持久化采用mongodb非结构化存储实现,以满足后续调整的灵活需要: