题目链接:

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. Tarjan算法初探 (1):Tarjan如何求有向图的强连通分量

    在此大概讲一下初学Tarjan算法的领悟( QwQ) Tarjan算法 是图论的非常经典的算法 可以用来寻找有向图中的强连通分量 与此同时也可以通过寻找图中的强连通分量来进行缩点 首先给出强连通分量的 ...

  2. Activity Monitor 闪退 & 无法进入睡眠

    情况描述 黑苹果主机突然无法进入睡眠. 考虑到可能是后台程序阻碍了系统正常进入睡眠, 于是想要通过Activity Monitor查看系统的活动情况,然而,Activity Monitor闪退. 重 ...

  3. 自学tensorflow——2.使用tensorflow计算线性回归模型

    废话不多说,直接开始 1.首先,导入所需的模块: import numpy as np import os import tensorflow as tf 关闭tensorflow输出的一大堆硬件信息 ...

  4. C语言__LINE__实现原理

    在test.c中写如下代码: 1 #include <stdio.h> 2 3 int main() 4 { 5     printf("line:%d\n", __L ...

  5. 如何在mac上运行vue项目

    使用终端安装Vue运行环境 1.安装 Homebrew Homebrew 是osx下面最优秀的包管理工具,没有之一.先在终端查看是否已安装brew brew -v 如果返回 Homebrew 的版本号 ...

  6. tkinter的GUI设计:界面与逻辑分离(二)-- 菜单栏

    由于要用到文件对话框和消息对话框,所以先给出下面的列表. py2 与 py3 中 tkinter 的变化: Tkinter → tkinter tkMessageBox → tkinter.messa ...

  7. BZOJ4543 Hotel加强版

    题面 $\text{BZOJ}$间接权限题 洛谷的弱化版 题解 三点距离两两相等要满足以下条件: 有一个相同的$\text{LCA}$ 所以如果存在一个点,使得另外两个点在它子树中,距离为$d$,且$ ...

  8. 做题记录 To 2019.2.13

    2019-01-18 4543: [POI2014]Hotel加强版:长链剖分+树形dp. 3653: 谈笑风生:dfs序+主席树. POJ 3678 Katu Puzzle:2-sat问题,给n个变 ...

  9. floodlight路由机制分析

    SDN的出现可以使得各种复杂的路由协议从原本的Device OS中剥离出来,放在SDN Controller中,Controller用一种简单的协议来和所有的Router进行通信,就可以获得网络拓扑, ...

  10. 【JUC源码解析】SynchronousQueue

    简介 SynchronousQueue是一种特殊的阻塞队列,该队列没有容量. [存数据线程]到达队列后,若发现没有[取数据线程]在此等待,则[存数据线程]便入队等待,直到有[取数据线程]来取数据,并释 ...