显然是状压,显然不可能把所有格子压起来

仔细观察发现只有机关周围的四个格子有用以及起点,所以我们用spfa处理出这些格子两两之间的距离(注意细节……这里写挂了好几次),然后设f[s][i]为碰完的机关石状态为s,现在在有用格子的第i个的最小停下次数,转移按照套路即可

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
const int N=105,dx[]={0,0,1,-1},dy[]={1,-1,0,0};
int n,m,t,a[N][N],f[70005][65],x[N],y[N],bx,by,dis[N][N][5],id[N][5],tot;
char c[N][N];
bool v[N][N];
struct qwe
{
int x,y;
qwe(int X=0,int Y=0)
{
x=X,y=Y;
}
};
bool ok(int x,int y)
{
return x>=1&&x<=n&&y>=1&&y<=m&&c[x][y]!='#';
}
void spfa(int sx,int sy,int s)
{//cerr<<sx<<" "<<sy<<endl;
if(!ok(sx,sy))
return;
// cerr<<s<<endl;
queue<qwe>q;
memset(dis,0x3f,sizeof(dis));
dis[sx][sy][0]=dis[sx][sy][1]=dis[sx][sy][2]=dis[sx][sy][3]=0;
v[sx][sy]=1;
q.push(qwe(sx,sy));
while(!q.empty())
{
int x=q.front().x,y=q.front().y;
q.pop();
v[x][y]=0;
for(int j=0;j<4;j++)
if(ok(x+dx[j],y+dy[j]))
for(int k=0;k<4;k++)
if(dis[x+dx[j]][y+dy[j]][k]>dis[x][y][j]+(j!=k))
{
dis[x+dx[j]][y+dy[j]][k]=dis[x][y][j]+(j!=k);
if(!v[x+dx[j]][y+dy[j]])
{
v[x+dx[j]][y+dy[j]]=1;
q.push(qwe(x+dx[j],y+dy[j]));
}
}
}
for(int i=1;i<=t;i++)
for(int j=0;j<4;j++)
for(int k=0;k<4;k++)
a[s][id[i][j]]=min(a[s][id[i][j]],dis[x[i]+dx[j]][y[i]+dy[j]][k]+(dx[j]+dx[k]!=0||dy[j]+dy[k]!=0));
}
int main()
{
scanf("%d%d%d",&n,&m,&t);
for(int i=1;i<=n;i++)
scanf("%s",c[i]+1);
for(int i=1;i<=t;i++)
scanf("%d%d",&x[i],&y[i]);
scanf("%d%d",&bx,&by);
for(int i=1;i<=t;i++)
for(int j=0;j<4;j++)
id[i][j]=++tot;
memset(a,0x3f,sizeof(a));
for(int i=1;i<=t;i++)
for(int j=0;j<4;j++)
spfa(x[i]+dx[j],y[i]+dy[j],id[i][j]);//,cerr<<x[i]<<" "<<dx[j]<<" "<<y[i]<<" "<<dy[j]<<endl;
spfa(bx,by,tot+1);
// for(int i=1;i<=tot+1;i++)
// {
// for(int j=1;j<=tot+1;j++)
// cerr<<a[i][j]<<" ";
// cerr<<endl;
// }
memset(f,0x3f,sizeof(f));
f[0][tot+1]=0;
for(int i=0,len=(1<<t)-1;i<=len;i++)
for(int j=1;j<=tot+1;j++)
for(int k=1;k<=tot;k++)
f[i|(1<<((k-1)/4))][k]=min(f[i|(1<<((k-1)/4))][k],f[i][j]+a[j][k]+1);
int ans=1e9;
for(int i=1;i<=tot;i++)
ans=min(ans,f[(1<<t)-1][i]);
printf("%d\n",ans);
return 0;
}

bzoj 1556: 墓地秘密【状压dp+spfa】的更多相关文章

  1. bzoj 1556 墓地秘密 —— 状压DP

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1556 预处理出两个障碍四个方向之间的距离(转弯次数),就可以状压DP了: 但预处理很麻烦.. ...

  2. 洛谷P2761 软件补丁问题(状压DP,SPFA)

    题意 描述不清... Sol 网络流24题里面怎么会有状压dp?? 真是狗血,不过还是简单吧. 直接用$f[sta]$表示当前状态为$sta$时的最小花费 转移的时候枚举一下哪一个补丁可以搞这个状态 ...

  3. BZOJ 1087 题解【状压DP】

    1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3112  Solved: 1816[Submit][ ...

  4. BZOJ 4000: [TJOI2015]棋盘( 状压dp + 矩阵快速幂 )

    状压dp, 然后转移都是一样的, 矩阵乘法+快速幂就行啦. O(logN*2^(3m)) ------------------------------------------------------- ...

  5. BZOJ 4057: [Cerc2012]Kingdoms( 状压dp )

    状压dp.... 我已开始用递归结果就 TLE 了... 不科学啊...我dp基本上都是用递归的..我只好改成递推 , 刷表法 将全部公司用二进制表示 , 压成一个数 . 0 表示破产 , 1 表示没 ...

  6. BZOJ 2073: [POI2004]PRZ( 状压dp )

    早上这道题没调完就去玩NOI网络同步赛了.... 状压dp , dp( s ) 表示 s 状态下所用的最短时间 , 转移就直接暴力枚举子集 . 可以先预处理出每个状态下的重量和时间的信息 . 复杂度是 ...

  7. HDU 4284 状压dp+spfa

    题意: 给定n个点 m条无向边 d元. 以下m行表示每条边 u<=>v 以及花费 w 以下top 以下top行 num c d 表示点标为num的城市 工资为c 健康证价格为d 目标是经过 ...

  8. bzoj 2669 题解(状压dp+搜索+容斥原理)

    这题太难了...看了30篇题解才整明白到底咋回事... 核心思想:状压dp+搜索+容斥 首先我们分析一下,对于一个4*7的棋盘,低点的个数至多只有8个(可以数一数) 这样的话,我们可以进行一个状压,把 ...

  9. BZOJ 2004 公交线路(状压DP+矩阵快速幂)

    注意到每个路线相邻车站的距离不超过K,也就是说我们可以对连续K个车站的状态进行状压. 然后状压DP一下,用矩阵快速幂加速运算即可. #include <stdio.h> #include ...

  10. BZOJ 1226 学校食堂(状压DP)

    状压DP f(i,j,k)表示前i−1个人已经吃了饭,且在i之后的状态为j的人也吃了饭(用二进制表示后面的状态),最后吃的那个人是i之后的第k个 (注意k可以是负数) 然后 如果j&1=1那么 ...

随机推荐

  1. virtualBox下Centos系统扩展磁盘空间

    (1)查看空间容量: 打开windows命令终端.然后打开virtualbox安装目录,找到VBoxManage.exe,拖动到终端里面.输入命令:list hdds,回车. 我安装的位置是 : C: ...

  2. 修改flex chart中Legend的字体样式

    最近在弄FLEX的图表, 发现CHART 中的Legend 的字体通过直接设置Style 并没有办法改变字体大小. google 了下, 发现了这个方法: 通过派生LegendItem类,并设置Leg ...

  3. ubuntu12.04安装搜狗输入法记录

    http://blog.sina.com.cn/s/blog_66fa66650101akip.html 看了http://www.cnblogs.com/A-Song/archive/2013/04 ...

  4. webx启动流程

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvTFRpYW5jaGFv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA ...

  5. VC++中的int main(int argc, char argv[])是什么意思

    这是C/C++的一重要函数,叫主函数.无论程序多复杂,代码中必须有这么一个函数,也只能有一个这样的函数:程序执行时就是从这个函数进入的.由于问得比较笼统,如果你想知道详细情况的话,发给你一个网友的求助 ...

  6. UVA 4857 Halloween Costumes 区间背包

    题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...

  7. 海思HI3516A开发板顺利上线

    有图有真相.

  8. 访问某类型的元数据的方式-TypeDescriptor 类

    .NET Framework 提供了两种访问某类型的元数据的方式:通过 System.Reflection 命名空间中提供的反射 API,以及通过 TypeDescriptor 类.反射是可用于所有类 ...

  9. Receiver type ‘X’ for instance message is a forward declaration

    这往往是引用的问题. ARC要求完整的前向引用,也就是说在MRC时代可能仅仅须要在.h中申明@class就能够,可是在ARC中假设调用某个子类中未覆盖的父类中的方法的话.必须对父类.h引用,否则无法编 ...

  10. 2016/2/25 html+css学习资源

    html+css学习资源 1.Position is Everything,一个描述和展示在各种浏览器中发现的bug,并提供css解决方法的网站,顶! 2.一个国外的网页设计论坛 3.http://c ...