题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=4568

Hunter

Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 32768/32768 K (Java/Others)
#### 问题描述
> One day, a hunter named James went to a mysterious area to find the treasures. James wanted to research the area and brought all treasures that he could.
>   The area can be represented as a N*M rectangle. Any points of the rectangle is a number means the cost of research it,-1 means James can't cross it, James can start at any place out of the rectangle, and explore point next by next. He will move in the rectangle and bring out all treasures he can take. Of course, he will end at any border to go out of rectangle(James will research every point at anytime he cross because he can't remember whether the point are researched or not).
>   Now give you a map of the area, you must calculate the least cost that James bring out all treasures he can take(one point up to only one treasure).Also, if nothing James can get, please output 0.
#### 输入
> The input consists of T test cases. The number of test cases T is given in the first line of the input. Each test case begins with a line containing 2 integers N M , (1输出

For each test case, you should output only a number means the minimum cost.

样例输入

2

3 3

3 2 3

5 4 3

1 4 2

1

1 1

3 3

3 2 3

5 4 3

1 4 2

2

1 1

2 2

样例输出

8

11

题意

给你一个n*m的迷宫,每个方格上标的是花费,现在有些坐标上有宝藏,你可以从边界的方格进入,最后需要从边界处离开,问你获得所有宝藏的最小花费,每个点可以重复走。

题解

构造一个超级节点,点权为0,与所有的边界相连。然后对所有的宝藏的点跑最短路。

重新构造只有宝藏和超级节点的图,任意两个点之间的路径为上面处理出来的最短路。

对于新图跑下TSP就ok啦。

代码

#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<ctime>
#include<vector>
#include<cstdio>
#include<string>
#include<bitset>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
using namespace std;
#define X first
#define Y second
#define mkp make_pair
#define lson (o<<1)
#define rson ((o<<1)|1)
#define mid (l+(r-l)/2)
#define sz() size()
#define pb(v) push_back(v)
#define all(o) (o).begin(),(o).end()
#define clr(a,v) memset(a,v,sizeof(a))
#define bug(a) cout<<#a<<" = "<<a<<endl
#define rep(i,a,b) for(int i=a;i<(b);i++)
#define scf scanf
#define prf printf typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
typedef vector<pair<int,int> > VPII; const int INF=1000000000;
const LL INFL=0x3f3f3f3f3f3f3f3fLL;
const double eps=1e-9; const double PI = acos(-1.0); //start---------------------------------------------------------------------- const int maxn=222; int mat[maxn][maxn];
int G[22][22];
PII arr[22];
int n,m;
int dp[1<<15][15]; struct HeapNode{
int x,y,d;
HeapNode(int x,int y,int d):x(x),y(y),d(d){}
bool operator < (const HeapNode& tmp) const {
return d>tmp.d;
}
}; int d[22][maxn][maxn];
bool done[maxn][maxn];
const int dx[]={-1,1,0,0};
const int dy[]={0,0,-1,1};
void dij(int id,int sx,int sy){
priority_queue<HeapNode> Q;
rep(i,0,n) rep(j,0,m) d[id][i][j]=INF;
d[id][sx][sy]=0; clr(done,0);
Q.push(HeapNode(sx,sy,0));
while(!Q.empty()){
HeapNode u=Q.top(); Q.pop();
int x=u.x,y=u.y;
if(done[x][y]) continue;
if(x==0||y==0||x==n-1||y==m-1){
d[0][sx][sy]=min(d[0][sx][sy],d[id][x][y]+mat[x][y]-mat[sx][sy]);
}
done[x][y]=true;
for(int i=0;i<4;i++){
int nx=x+dx[i],ny=y+dy[i];
if(nx<0||nx>=n||ny<0||ny>=m) continue;
if(mat[nx][ny]==-1) continue;
if(d[id][nx][ny]>d[id][x][y]+mat[x][y]){
d[id][nx][ny]=d[id][x][y]+mat[x][y];
Q.push(HeapNode(nx,ny,d[id][nx][ny]));
}
}
}
} void init(){
rep(i,0,n) rep(j,0,m) d[0][i][j]=INF;
} int main() {
int tc,kase=0;
scf("%d",&tc);
while(tc--) {
scf("%d%d",&n,&m);
init();
rep(i,0,n) rep(j,0,m){
scf("%d",&mat[i][j]);
} int q;
scf("%d",&q);
for(int i=1;i<=q;i++) scf("%d%d",&arr[i].X,&arr[i].Y); ///dijkstra
for(int i=1;i<=q;i++){
dij(i,arr[i].X,arr[i].Y);
} ///TSP
///build
rep(i,0,22) rep(j,0,22) G[i][j]=INF;
rep(i,0,22) G[i][i]=0;
for(int i=0;i<=q;i++){
for(int j=0;j<=q;j++){
if(j==i) continue;
if(j==0){
G[i][j]=G[j][i]+mat[arr[i].X][arr[i].Y];
continue;
}
G[i][j]=d[i][arr[j].X][arr[j].Y];
}
} ///init
rep(i,0,(1<<15)) rep(j,0,15) dp[i][j]=INF;
dp[1][0]=0; ///通路
q++;
for(int i=2;i<(1<<q);i++){
for(int j=0;j<q;j++){
if(i&(1<<j)){
for(int k=0;k<q;k++){
if(k==j||!(i&(1<<k))) continue;
dp[i][j]=min(dp[i][j],dp[i^(1<<j)][k]+G[k][j]);
}
}
}
} ///回路
int ans=INF;
for(int i=1;i<q;i++){
ans=min(ans,dp[(1<<q)-1][i]+G[i][0]);
} if(ans>=INF) prf("0\n");
else prf("%d\n",ans); }
return 0;
} //end-----------------------------------------------------------------------

HDU 4568 Hunter 最短路+TSP的更多相关文章

  1. hdu 4568 Hunter 最短路+dp

    Hunter Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Subm ...

  2. HDU 4568 Hunter 最短路+状压DP

    题意:给一个n*m的格子,格子中有一些数,如果是正整数则为到此格子的花费,如果为-1表示此格子不可到,现在给k个宝藏的地点(k<=13),求一个人从边界外一点进入整个棋盘,然后拿走所有能拿走的宝 ...

  3. hdu 4568 Hunter bfs建图+TSP状压DP

    想AC的人请跳过这一段... 题目应该都能读懂.但是个人觉得这题出的很烂,意思太模糊了. 首先,进出次数只能是一次!!这个居然在题目中没有明确说明,让我在当时看到题目的时候无从下手. 因为我想到了这几 ...

  4. HDU 4568 Hunter(最短路径+DP)(2013 ACM-ICPC长沙赛区全国邀请赛)

    Problem Description One day, a hunter named James went to a mysterious area to find the treasures. J ...

  5. hdu 4568 Hunter(spfa预处理 + 状压dp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4568 思路:首先spfa预处理出每对宝藏之间的最短距离以及宝藏到边界的最短距离,然后dp[state] ...

  6. hdu 4568(SPFA预处理+TSP)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4568 思路:先用spfa预处理出宝藏与宝藏之间的最短距离,宝藏到边界的最短距离,然后就是经典的求TSP ...

  7. HDU 4568 SPFA + TSP

    这道题是长沙邀请赛的题,当时是道签到题. 这种题还是很常见的,讲一下思路. 首先是预处理出每个宝藏之间的距离,还有到边的距离,直接对每个宝藏进行一次SPFA就可以了. 然后就是经典的求TSP的过程. ...

  8. HDU 5067 (状态压缩DP+TSP)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5067 题目大意:蓝翔挖掘机挖石子.把地图上所有石子都运回起点,问最少耗时. 解题思路: 首先得YY出 ...

  9. HDU 4856 (状态压缩DP+TSP)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4856 题目大意:有一个迷宫.迷宫里有些隧道,每个隧道有起点和终点,在隧道里不耗时.出隧道就耗时,你的 ...

随机推荐

  1. linux 系统运行级别一般为 0-6,请分别写出每个级别的含义

    每个运行级别的含义 0   关机模式(不要把启动级别  运行级别设置为0) 1   单用户模式 2   无NFS多用户模式 3   文本模式(命令行模式,完整的多用户模式) 4   未使用的 5   ...

  2. golang cgo 使用总结

    原文地址 CGO 提供了 golang 和 C 语言相互调用的机制.某些第三方库可能只有 C/C++ 的实现,完全用纯 golang 的实现可能工程浩大,这时候 CGO 就派上用场了.可以通 CGO ...

  3. 修复Gradle CreateProcess error=206

    插件地址:https://plugins.gradle.org/plugin/ua.eshepelyuk.ManifestClasspath 修复Window系统中Gradle 路径太长问题, Fix ...

  4. Mysql linux 安装文档

    1.安装依赖包 yum -y install gcc-c++ ncurses-devel cmake make perl gcc autoconf automake zlib libxml libgc ...

  5. 10.21 (上午) 开课一个月零十七天 (PHP基础语法)

    <?php $a = 6; echo $a; //注释语法 /* 多行注释 */ //输出语法 echo "hello"; echo "world",&q ...

  6. 安装spark-1.5遇到的一些问题

    1.java.lang.UnsatisfiedLinkError: org.apache.hadoop.util.NativeCodeLoader.buildSupportsSnappy()Z 这个问 ...

  7. 解决Linux下编译.sh文件报错 unexpected operator Syntax error: word unexpected

    执行一个脚本  发现报语法错误,但是在其他机器上运行都没有问题 唯一的区别就是 一个是centos机器  报错的是ubuntu 网上搜索了一下 因为Ubuntu默认的sh是连接到dash的,又因为da ...

  8. python之shutil模块详解

    shutil模块 -- --High-level file operations  高级的文件操作模块. os模块提供了对目录或者文件的新建/删除/查看文件属性,还提供了对文件以及目录的路径操作.比如 ...

  9. Python爬虫入门 之 如何在豆瓣中获取自己喜欢的TOP N电影信息

    什么是爬虫 按照一定规则自动的获取互联网上的信息(如何快速有效的利用互联网上的大量信息) 爬虫的应用 搜索引擎(Google.百度.Bing等搜索引擎,辅助人们检索信息) 股票软件(爬取股票数据,帮助 ...

  10. [Selenium]如何通过Selenium实现Ctrl+click,即按住Ctrl的同时进行单击操作

    [以下是不负责任的转载……] 在自动化测试的过程中,经常会出现这样的场景: 按住Ctrl的同时,进行单击操作,已达到多选的目的 Actions a = new Actions(driver); a.k ...