题目链接:

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. C++重载运算符练习--对people类重载“= =”运算符和“=”运算符

    题目描述 对people类重载“= =”运算符和“=”运算符,“==”运算符判断两个people类对象的id属性是否相等:“=”运算符实现people类对象的赋值操作. 代码如下 #include&l ...

  2. Ubuntu18.04编译S3的Linux SDK(Zeta)

    按照S3官方Wiki(http://www.sochip.com.cn/s3)的陈述,推荐使用Ubuntu16.04作为Host端系统,笔者是一名乐于并热衷于尝鲜的搬砖工,于是,尝试在最新的18.04 ...

  3. GoLand(三)数据类型、变量和常量

    Infi-chu: http://www.cnblogs.com/Infi-chu/ 一.数据类型 数据类型的出现是为了把数据分成所需内存大小不同的数据,编程的时候需要用大数据的时候才需要申请大内存, ...

  4. 安装luasocket 的正确姿势

    在lua中用下面这种方式使用socket,安装luasocket-2.0.2后老是报一些莫名其妙的错误. require("socket") 下面是部分报错信息 lua: erro ...

  5. 不能存在多个@ManyToMany(fetch=FetchType.EAGER)

    @LazyCollection(LazyCollectionOption.FALSE) 原地址:https://stackoverflow.com/questions/4334970/hibernat ...

  6. WPF DatePicker 添加水印效果

    这个控件没有水印属性,依然使用依赖属性解决 public class DatePickerHelper { public static object GetWatermark(DependencyOb ...

  7. BZOJ1026_windy数_KEY

    题目传送门 数位DP,其实只要求1~A-1和1~B就可以了.两数相减即为答案. 考虑怎们求1~A. 设f[i][j]表示到第i位,为j的windy数总数. 由前一位差值大于1的方程转移. 但是统计答案 ...

  8. 03、 forms组件

    1.校验字段功能 1.reg页面准备 models from django.db import models class UserInfo(models.Model): useranme = mode ...

  9. Python 学习 第五篇:语句和语法

    Python程序是语句构成的,语句包含表达式,表达式嵌套在语句中,包含变量和常量,用于处理对象.Python的语法实质上是由表达式.语句和代码块构成的.语句是由表达式构成的,代码块是由多个语句构成的复 ...

  10. asp.net core结合NLog搭建ELK实时日志分析平台

    0.整体架构 整体架构目录:ASP.NET Core分布式项目实战-目录 一.介绍ELK 1.说明(此篇ELK采用rpm的方式安装在服务器上)-牛刀小试 承接上一篇文章的内容准备部署ELK来展示asp ...