这道题是长沙邀请赛的题,当时是道签到题。

这种题还是很常见的,讲一下思路。

首先是预处理出每个宝藏之间的距离,还有到边的距离,直接对每个宝藏进行一次SPFA就可以了。

然后就是经典的求TSP的过程。

#include <set>
#include <map>
#include <stack>
#include <cmath>
#include <queue>
#include <cstdio>
#include <string>
#include <vector>
#include <iomanip>
#include <cstring>
#include <iostream>
#include <algorithm>
#define Max 2505
#define FI first
#define SE second
#define ll long long
#define PI acos(-1.0)
#define inf 1111111111
#define LL(x) ( x << 1 )
#define bug puts("here")
#define PII pair<int,int>
#define RR(x) ( x << 1 | 1 )
#define mp(a,b) make_pair(a,b)
#define mem(a,b) memset(a,b,sizeof(a))
#define infA(a) for (int i = 0 ; i <= n ; ++ i)a[i] = inf ;
#define REP(i,s,t) for( int i = ( s ) ; i <= ( t ) ; ++ i ) using namespace std; inline void RD(int &ret) {
char c;
do {
c = getchar();
} while(c < '0' || c > '9') ;
ret = c - '0';
while((c=getchar()) >= '0' && c <= '9')
ret = ret * 10 + ( c - '0' );
} inline void OT(int a) {
if(a >= 10)OT(a / 10) ;
putchar(a % 10 + '0') ;
}
#define N 222
#define K 15 int Map[N][N] ;
struct tru {
int x ,y ;
} tk[K] ;
int tt ;
int MM[K][K] ;
int dp[1 << K][K] ;
int dis[N][N] ;
bool vis[N][N] ;
PII qe[1111111] ;
int D[K] ;
int n , m ;
int mx[4] = {0 , 0 , 1 , -1} ;
int my[4] = {1 , -1 , 0 , 0} ;
int inmap(int x ,int y) {
if(x >= 0 && x < n && y >= 0 && y < m && Map[x][y] != -1)return 1 ;
return 0 ;
}
void init(int pos) {
for (int i = 0 ; i < n ; i ++ ) {
for (int j = 0 ; j < m ; j ++ ) {
dis[i][j] = inf ;
vis[i][j] = 0 ;
}
}
dis[tk[pos].x][tk[pos].y] = Map[tk[pos].x][tk[pos].y] == -1 ? inf : 0 ;
int h = 0 , t = 0 ;
qe[h ++ ] = mp(tk[pos].x ,tk[pos].y) ;
while(h > t) {
PII tp = qe[t ++ ] ;
vis[tp.FI][tp.SE] = 0 ;
if(tp.FI == 0 || tp.FI == n - 1 || tp.SE == 0 || tp.SE == m - 1) {
D[pos] = min(D[pos] , dis[tp.FI][tp.SE]) ;
}
for (int i = 0 ; i < 4 ; i ++ ) {
int tx = tp.FI + mx[i] ;
int ty = tp.SE + my[i] ;
if(inmap(tx , ty)) {
if(dis[tx][ty] > dis[tp.FI][tp.SE] + Map[tx][ty]) {
dis[tx][ty] = dis[tp.FI][tp.SE] + Map[tx][ty] ;
if(!vis[tx][ty]) {
vis[tx][ty] = 1 ;
qe[h ++ ] = mp(tx ,ty) ;
}
}
}
}
}
} int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin) ;
freopen("out.txt","w",stdout) ;
#endif
int T ;
cin >> T ;
while ( T -- ) {
cin >> n >> m ;
REP(i , 0, n - 1 ) {
REP(j , 0 , m - 1)scanf("%d",&Map[i][j]) ;
}
cin >> tt ;
REP(i , 0 , tt - 1) {
RD(tk[i].x) ;
RD(tk[i].y) ;
}
REP(i , 0 , tt - 1) {
REP(j , 0 , tt - 1) {
MM[i][j] = inf ;
}
MM[i][i] = 0 ;
D[i] = inf ;
}
for (int i = 0 ; i < (1 << tt) ; i ++ ) {
for (int j = 0 ; j < tt ; j ++ )dp[i][j] = inf ;
} REP(i , 0 , tt - 1) {
init(i) ;
REP(j , 0 , tt - 1) {
if(i == j)continue ;
MM[i][j] = min(MM[i][j] , dis[tk[j].x][tk[j].y]) ;//宝藏到宝藏之间的最近距离
}
dp[1 << i][i] = D[i] + Map[tk[i].x][tk[i].y] ;//该宝藏到达边的最近距离
}
for (int i = 0 ; i < 1 << tt ; i ++ ) {
for (int j = 0 ; j < tt ; j ++ ) {
if(i & (1 << j) == 0)continue ;
if(dp[i][j] == inf)continue ;
for (int k = 0 ; k < tt ; k ++ ) {
if(i & (1 << k))continue ;
int tp = i | (1 << k) ;
dp[tp][k] = min(dp[tp][k] , dp[i][j] + MM[j][k]) ;
}
}
}
int ans = inf ;
for (int i = 0 ; i < tt ; i ++ ) {
ans = min(ans , dp[(1 << tt) - 1][i] + D[i] ) ;
}
cout << ans << endl;
}
return 0 ;
}
/*
5
4 4
3 3 3 3
3 -1 -1 -1
3 -1 3 3
3 -1 -1 -1
1
2 2 5 5
1 1 1 1 1
1 -1 -1 -1 -1
1 -1 -1 -1 -1
1 -1 -1 -1 -1
1 -1 -1 -1 -1
2
4 0
0 4 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 */

HDU 4568 SPFA + TSP的更多相关文章

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

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

  2. hdu 4568 Hunter 最短路+dp

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

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

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

  4. HDU 4568 Hunter 最短路+TSP

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4568 Hunter Time Limit: 2000/1000 MS (Java/Others)Me ...

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

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

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

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

  7. HDU 1619 Unidirectional TSP(单向TSP + 路径打印)

    Unidirectional TSP Problem Description Problems that require minimum paths through some domain appea ...

  8. HDU 1317XYZZY spfa+判断正环+链式前向星(感觉不对,但能A)

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

  9. Key Vertex (hdu 3313 SPFA+DFS 求起点到终点路径上的割点)

    Key Vertex Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Tota ...

随机推荐

  1. FPGA学习笔记. 二分频和三分频

    二分频和三分频 二分频:将输入频率CLK分为原来的 1/2 . 实现:在每次CLK的上升沿或下降沿将输出翻转. 三分频: 1/3占空比. 实现:可使用上升沿或下降沿计数生成输出.需要一个两位计数器. ...

  2. 工具类。父类(Pom文件)

    ego_parent(pom文件) <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="ht ...

  3. py-faster-rcnn代码阅读3-roidb.py

    roidb是比较复杂的数据结构,存放了数据集的roi信息.原始的roidb来自数据集,在trian.py的get_training_roidb(imdb)函数进行了水平翻转扩充数量,然后prepare ...

  4. phantomhs获取网页的高度

    function heheda() { window.setTimeout(function () { console.log("---------------------Capture O ...

  5. Linux:安装mysql

    #install mysql$ rpm -ivh MySQL-client-5.5.28-1.rhel5.x86_64.rpm --nodeps$ rpm -ivh MySQL-server-5.5. ...

  6. Windows安装pycrypto失败记录

    Windows 10家庭中文版,Python 3.6.4, 180824测试前端加密文本在后台揭秘,查询后发现,可以使用pycrypto模块实现,那么,安装它(pip),结果安装失败了. 本文暂时记录 ...

  7. activiti流程跟踪图算法

    流程跟踪图-推导算法 工作中使用activiti实现流程图相关业务,但是上线后遇到问题,偶尔流程图出不来.查阅了一下画流程图的实现,基本上是参见:activiti-流程图颜色变化之一篇. 核心类,参见 ...

  8. maven dependencies 报错

    maven配置的环境变量有问题: 用最新的maven替换系统默认的setting.xml文件即可

  9. 移动网络简介与RRC

    1.移动网络简介 1G:表示第一代移动通讯技术,以模拟技术为基础的蜂窝无线电话系统,如现在已经淘汰的模拟移动网.1G无线系统在设计上只能传输语音流量,并受到网络容量的限制. 2G:第二代手机通信技术规 ...

  10. 重装Ubuntu时如何保留/home分区中的数据

    重装Ubuntu时如何保留/home分区中的数据作者:maowang Windows系统可以在重装时只格式化C盘,从而保留其他分区的数据. Ubuntu系统也可以,只要在安装系统时分出一个/home分 ...