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

解法:看到k的范围应该想到状态压缩,将每个格子都看成一个点,再新建两个点,一个表示边界外的起点,用0表示,一个表示边界外的终点,用n*m+1表示,然后相互建边,建有向边,边权为终点格子的花费值,(其实都不用建边,直接跑最短路也行)然后求这k+2个点两两之间的最短距离,然后就化成TSP问题了,用状压DP可以解决。

求k+2个点两两之间的最短距离可以跑k+2次SPFA求出,复杂度不高。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <queue>
#include <algorithm>
#define Mod 1000000007
using namespace std;
#define N 10007 int mp[][];
int C[][];
int dis[][];
int n,m,k;
int d[];
struct node
{
int v,w,next;
}G[*];
int head[*],tot;
int dx[] = {,,,-};
int dy[] = {,-,,};
int vis[];
struct Point
{
int x,y;
}P[]; int OK(int nx,int ny)
{
if(nx >= && nx <= n && ny >= && ny <= m)
return ;
return ;
} void addedge(int u,int v,int w)
{
G[tot].v = v;
G[tot].w = w;
G[tot].next = head[u];
head[u] = tot++;
} void SPFA(int s)
{
queue<int> que;
memset(vis,,sizeof(vis));
que.push(s);
for(int i=;i<=n*m+;i++) d[i] = Mod;
d[s] = , vis[s] = ;
while(!que.empty())
{
int u = que.front();
que.pop();
vis[u] = ;
for(int i=head[u];i!=-;i=G[i].next)
{
int v = G[i].v;
int w = G[i].w;
if(d[v] > d[u] + w)
{
d[v] = d[u] + w;
if(!vis[v])
vis[v] = ,que.push(v);
}
}
}
} int dp[<<][]; int main()
{
int i,j;
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(i=;i<=n;i++)
for(j=;j<=m;j++)
{
scanf("%d",&C[i][j]);
if(C[i][j] == -)
C[i][j] = Mod;
}
memset(head,-,sizeof(head));
tot = ;
for(i=;i<=n;i++)
{
for(j=;j<=m;j++)
{
int now = (i-)*m + j;
for(int h=;h<;h++)
{
int kx = i + dx[h];
int ky = j + dy[h];
if(!OK(kx,ky))
continue;
int tmp = (kx-)*m + ky;
addedge(now,tmp,C[kx][ky]);
}
if(i == || i == n || j == || j == m) //边界
{
addedge(,now,C[i][j]);
addedge(now,n*m+,);
}
}
}
scanf("%d",&k);
P[].x = , P[].y = ;
P[k+].x = n,P[k+].y = m+;
for(i=;i<=k;i++)
scanf("%d%d",&P[i].x,&P[i].y),P[i].x++,P[i].y++;
for(i=;i<=k+;i++)
{
int s = (P[i].x-)*m + P[i].y;
SPFA(s);
for(j=;j<=k+;j++)
{
if(i == j) continue;
int v = (P[j].x-)*m + P[j].y;
dis[i][j] = d[v];
}
}
for(i=;i<(<<);i++)
for(j=;j<;j++)
dp[i][j]=Mod;
for(i=;i<k;i++)
dp[<<i][i+]=dis[][i+];
for(i=;i<(<<k);i++)
{
for(int kk=;kk<k;kk++)
{
if(!(i&(<<kk)))continue;
for(int j=;j<k;j++)
{
if(i&(<<j)) continue;
dp[i+(<<j)][j+]=min(dp[i+(<<j)][j+],dp[i][kk+]+dis[kk+][j+]);
}
}
}
int minn=Mod;
for(i=;i<=k;i++)
minn=min(dp[(<<k)-][i]+dis[i][k+],minn);
if(minn == Mod)
cout<<<<endl;
else
cout<<minn<<endl;
}
return ;
}

HDU 4568 Hunter 最短路+状压DP的更多相关文章

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

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

  2. hdu 4568 Hunter 最短路+dp

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

  3. HDU 6149 Valley Numer II 状压DP

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6149 题意:中文题目 解法:状压DP,dp[i][j]代表前i个低点,当前高点状态为j的方案数,然后枚 ...

  4. HDU 5434 Peace small elephant 状压dp+矩阵快速幂

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5434 Peace small elephant  Accepts: 38  Submissions: ...

  5. 最短路+状压DP【洛谷P3489】 [POI2009]WIE-Hexer

    P3489 [POI2009]WIE-Hexer 大陆上有n个村庄,m条双向道路,p种怪物,k个铁匠,每个铁匠会居住在一个村庄里,你到了那个村庄后可以让他给你打造剑,每个铁匠打造的剑都可以对付一些特定 ...

  6. HDU 1074 Doing Homework(状压DP)

    第一次写博客ORZ…… http://acm.split.hdu.edu.cn/showproblem.php?pid=1074 http://acm.hdu.edu.cn/showproblem.p ...

  7. 【BZOJ1097】[POI2007]旅游景点atr 最短路+状压DP

    [BZOJ1097][POI2007]旅游景点atr Description FGD想从成都去上海旅游.在旅途中他希望经过一些城市并在那里欣赏风景,品尝风味小吃或者做其他的有趣的事情.经过这些城市的顺 ...

  8. HDU3247 Resource Archiver —— AC自动机 + BFS最短路 + 状压DP

    题目链接:https://vjudge.net/problem/HDU-3247 Resource Archiver Time Limit: 20000/10000 MS (Java/Others)  ...

  9. HDU - 4284 Travel(floyd+状压dp)

    Travel PP loves travel. Her dream is to travel around country A which consists of N cities and M roa ...

随机推荐

  1. SQL数据库基础(三)

    认识数据库备份和事务日志备份 数据库备份与日志备份是数据库维护的日常工作,备份的目的是在于当数据库出现故障或者遭到破坏时可以根据备份的数据库及事务日志文件还原到最近的时间点将损失降到最低点. 数据库备 ...

  2. [程序人生]前途无"亮‘’的大学

    转眼之间就到大四了,今天晚上很迷茫,很纠结,想了好多,好多,真的,长大之后,自从第一次失恋之后,第一次会想到这么的多.     嗯,先自我介绍哈吧,我是从云南的大山里走出来的孩子,什么样的大山,就是到 ...

  3. css清除浮动定位造成的异常

    清除浮动是为了解决高度塌陷的问题:内层有好几个div有宽有高,并且选择了浮动定位,但是外层的div却并没有设置宽高.在非IE浏览器(如Firefox)下,当容器的高度为auto,且容器的内容中有浮动( ...

  4. 通过FTP连接Azure上的网站

    下载发布文件 使用记事本(或其他文本工具)打开 找到ftp连接地址以及用户名.密码 使用ftp工具进行连接 输入相应参数,连接即可

  5. 基于MATLAB实现的云模型计算隶属度

    ”云”或者’云滴‘是云模型的基本单元,所谓云是指在其论域上的一个分布,可以用联合概率的形式(x, u)来表示 云模型用三个数据来表示其特征 期望:云滴在论域空间分布的期望,一般用符号Εx表示. 熵:不 ...

  6. R语言学习笔记:分析学生的考试成绩

    孩子上初中时拿到过全年级一次考试所有科目的考试成绩表,正好可以用于R语言的统计分析学习.为了不泄漏孩子的姓名,就用学号代替了,感兴趣可以下载测试数据进行练习. num class chn math e ...

  7. android XMl 解析神奇xstream 一: 解析android项目中 asset 文件夹 下的 aa.xml 文件

    简介 XStream 是一个开源项目,一套简单实用的类库,用于序列化对象与 XML 对象之间的相互转换. 将 XML 文件内容解析为一个对象或将一个对象序列化为 XML 文件. 1.下载工具 xstr ...

  8. c++ const用法小结

    const用法 1,定义全局变量的内存分配问题 #define  Pi_1  3.14       //使用#define宏 const double Pi_2 = 3.14    //使用const ...

  9. Mac搭建本地svn服务器,并用Cornerstone连接服务器

    Mac默认已经安装了svn,我们只需要进行配置并开启就可以了 首先我们可以验证一下是否安装了svn,打开终端,输入命令 svnserve --version 这里可以看到目前svn的版本号,说明已经安 ...

  10. android基础开发之RecycleView(1)---基本使用方式

    RecycleView是google为了优化listview,gridview 提供的一个新的控件. 1.android 导入recycleview 在app的gradle里面加入: dependen ...