传送门:Problem P3956

https://www.cnblogs.com/violet-acmer/p/9827010.html

题解:

  BFS

  相关变量解释:

    color[maxn][maxn];...................................color[ i ][ j ] : ( i , j )点的颜色,-1代表无色
    dp[maxn][maxn];.......................................dp[ i ][ j ] : 从( 1 , 1 )点到( i , j )点需要花费的最少金币
    magic[maxn][maxn];..................................magic[ i ][ j ] : 判断 ( i , j )点是否使用魔法
    in[maxn][maxn];.........................................in[ i ][ j ] : 判断( i , j )点是否在队列中

  具体步骤:

    初始,将(1,1)点加入队列中;

    (1):保存队头元素并弹出

    (2):每次,判断当前点的上下左右点是否可以通过当前点使dp[ ][ ]变小,如果可以,更新dp[ ][ ],如果被更新的点不在队列中,加入队列

    (3):重复(2)过程,直到队列为空

AC代码:

 #include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
#define INF 0x3f3f3f3f
#define P pair<int ,int >
#define mem(a,b) memset(a,b,sizeof a)
const int maxn=+; int m,n;
int color[maxn][maxn];
int dp[maxn][maxn];
bool marge[maxn][maxn];
bool in[maxn][maxn];
queue<P >myqueue;
int dx[]={-,,,};
int dy[]={,,-,};
bool isSat(int val)
{
return val >= &&val <= m;
}
void Solve()
{
dp[][]=;//初始化dp[1][1],并将其加入到队列中
myqueue.push(P(,));
while(!myqueue.empty())//步骤(3)
{
P p=myqueue.front();//步骤(1)
myqueue.pop();
in[p.first][p.second]=false;
for(int i=;i < ;++i)//步骤(2)
{
int x=p.first+dx[i];
int y=p.second+dy[i];
if(isSat(x) && isSat(y))
{
if(!marge[p.first][p.second])//如果当前点的未使用过魔法的,也就意味这当前点的颜色是本身就有的
{
if(!marge[x][y])//如果与当前点相邻的点(x,y)也为曾使用过魔法
{
if(color[x][y] != -)//如果点(x,y)有色,但并不是因为魔法而产生的
{
//如果当前点可以放缩dp[x][y]
if(dp[x][y] > dp[p.first][p.second]+(color[x][y] != color[p.first][p.second]))
{
dp[x][y]=dp[p.first][p.second]+(color[x][y] != color[p.first][p.second]);
if(!in[x][y])//被放缩的点(x,y)如果不在队列中,加入队列
in[x][y]=true,myqueue.push(P(x,y));
}
}
else//如果无色,通过使用魔法将其变为与当前点颜色相同的点,并被放缩了dp[][]
{
marge[x][y]=true;
color[x][y]=color[p.first][p.second];
dp[x][y]=dp[p.first][p.second]+;
if(!in[x][y])
in[x][y]=true,myqueue.push(P(x,y));
}
}
else if(dp[x][y] > dp[p.first][p.second]+)//如果点(x,y)在之前使用过魔法,就需要判断,当前为使用过魔法的点是否可以放缩dp[x][y]
{
dp[x][y]=dp[p.first][p.second]+;
color[x][y]=color[p.first][p.second];
if(!in[x][y])
in[x][y]=true,myqueue.push(P(x,y));
}
}
else if(!marge[x][y] && color[x][y] != -)//如果当前点的使用过魔法的,也就意味这当前点的颜色是通过魔法变来的,那么,只有当其临近点(x,y)含有的颜色是其本身就有的才有资格判断是否可以被放缩
{
if(dp[x][y] > dp[p.first][p.second]+(color[x][y] != color[p.first][p.second]))
{
dp[x][y]=dp[p.first][p.second]+(color[x][y] != color[p.first][p.second]);
if(!in[x][y])
myqueue.push(P(x,y)),in[x][y]=true;
}
}
}
}
}
printf("%d\n",dp[m][m] == INF ? -:dp[m][m]);
}
void Init()
{
mem(dp,INF);
mem(in,false);
mem(marge,false);
mem(color,-);
}
int main()
{
scanf("%d%d",&m,&n);
Init();
for(int i=;i <= n;++i)
{
int x,y;
scanf("%d%d",&x,&y);
scanf("%d",&color[x][y]);
}
Solve();
}

  

洛谷 P3956 棋盘(BFS)的更多相关文章

  1. 2017普及组D1T3 洛谷P3956 棋盘

    2017普及组D1T3 洛谷P3956 棋盘 原题 题目描述 有一个m×m的棋盘,棋盘上每一个格子可能是红色.黄色或没有任何颜色的.你现在要从棋盘的最左上角走到棋盘的最右下角. 任何一个时刻,你所站在 ...

  2. 洛谷 P3956 棋盘 解题报告

    P3956 棋盘 题目描述 有一个\(m×m\)的棋盘,棋盘上每一个格子可能是红色.黄色或没有任何颜色的.你现在要从棋盘的最左上角走到棋盘的最右下角. 任何一个时刻,你所站在的位置必须是有颜色的(不能 ...

  3. 洛谷 P3956 棋盘

    题目描述 有一个m ×m的棋盘,棋盘上每一个格子可能是红色.黄色或没有任何颜色的.你现在要从棋盘的最左上角走到棋盘的最右下角. 任何一个时刻,你所站在的位置必须是有颜色的(不能是无色的), 你只能向上 ...

  4. 洛谷 P3956 棋盘(记忆化搜索)

    嗯... 题目链接:https://www.luogu.org/problem/P3956 这是一道比较好搜的题,注意一些剪枝.预处理和魔法的处理问题(回溯). AC代码: #include<c ...

  5. 洛谷 P3956 棋盘 题解

    每日一题 day5 打卡 Analysis 深搜+剪枝+瞎jb判断 1.越界 2.这个点无色 3.当前的价值已经比答案大 三种情况要剪枝 我搜索里判断要不要施法的时候没判断上一次有没有施法,白调了0. ...

  6. 洛谷p3956 棋盘(NOIP2017 t3)

    在noip考场上本来以为只能骗暴力分,没想到最后A了: 本蒟蒻的做法比较简(zhi)单(zhang):记忆化深搜(考场上本来是想打广搜的,但我深搜稳一点就这样打了): 具体:每个点用一个f数组记录当前 ...

  7. 洛谷P1436 棋盘分割

    洛谷题目链接 动态规划: 我们设状态$f[i][j][o][p][k]$表示一个矩形,左上角顶点坐标为$(i,j)$,右下角顶点坐标为$(o,p)$时分割了$k$次,也就是说现在是$k+1$块 我们考 ...

  8. 【洛谷p3956】棋盘

    日常blog(✧◡✧) 棋盘[题目链接] 算法: 然后这是2017普及组: first.关于颜色处理:让c[i][j]=color+1:这样无色=0,红色=1,黄色=2: 然后其实是记忆化,将记答案的 ...

  9. 洛谷 P1141【BFS】+记忆化搜索+染色

    题目链接:https://www.luogu.org/problemnew/show/P1141 题目描述 有一个仅由数字 0 与 1 组成的n×n 格迷宫.若你位于一格0上,那么你可以移动到相邻 4 ...

随机推荐

  1. 添加php的memcached扩展模块

    memcached服务直接用yum安装[root@localhost ~]# yum install memcached 然后启动memcache服务,启动多个实例[root@localhost ~] ...

  2. Centos7.5部署MySQL5.7基于GTID主从复制+并行复制+半同步复制+读写分离(ProxySQL) 环境- 运维笔记 (完整版)

    之前已经详细介绍了Mysql基于GTID主从复制的概念,原理和配置,下面整体记录下MySQL5.7基于GTID主从复制+并行复制+增强半同步复制+读写分离环境的实现过程,以便加深对mysql新特性GT ...

  3. Fedora 19安装mysql

    安装数据库模块 Mysql和Mysql-server#yum install mysql mysql-server 开启mysql服务#systemctl start mysqld.service同样 ...

  4. Visual studio2015 编译时提示“GenerateResource”任务意外失败。

    今天弄了一个winfrom程序,狗血,一直报错,在另一台电脑上就不报错. 错误如下图 其实这样也能运行,但就是代码改之后,没有办法调试.搜了很久,发现了一种解决办法,完美解决. 最终成功了.

  5. SRS用例

    团队项目:超市管理系统     作者:王琨  个人博客地址:http://www.cnblogs.com/wangkun123 一. 用例视图概述 一般的超市商品管理系统,主要由五大模块组成,即商品信 ...

  6. 结对项目 https://github.com/quchengyu/jiedui/tree/quchengyu-patch-1

    所选项目名称:文本替换      结对人:傅艺伟 github地址 : https://github.com/quchengyu/jiedui/tree/quchengyu-patch-1 用一个新字 ...

  7. CMake系列之四:多个源文件-多个目录

    多个源文件,多个目录 现在进一步将MathFunctions.c和MathFunctions.h文件移到math目录下: ./Demo3 | +--- main.c | +--- math/ | +- ...

  8. 申港集中运营平台Linux测试环境架构搭建

    架构图 服务一览 ESB安装 ESB全称为Enterprise Service Bus,即企业服务总线.ESB提供了网络中最基本的连接中枢,是构筑企业神经系统的必要元素.ESB的出现改变了传统的软件架 ...

  9. SpringMVC 网站

    https://mp.weixin.qq.com/s/MLCIcQcevLBpZFOQce3DMQ

  10. [学习笔记]Ubuntu下安装配置SQLSERVER2017

    摘要自微软官网: https://docs.microsoft.com/zh-cn/sql/linux/quickstart-install-connect-ubuntu 安装步骤: 1. 导入公共秘 ...