题目传送门

建图

首先,根据题目,可以判断出这是一道最短路计数问题。

但是要跑最短路,首先要用他给的信息建图,这是非常关键的一步。

根据题意,我们可以想出以下建图规则:

  • 起点或是一个空白处可以花费 \(1\) 代价走向其八个方向。

  • 若走到了莲叶上,则可以继续向莲叶的八个方向走,并且还是只花费 \(1\) 代价。

  • 石头不能被走到。

  • 不能有点在以一个固定点出发的路径上被走到两次(不是最优了)。

由于权值(代价)只有 \(1\),所以不必记录,有边就代表 \(1\) 代价了。

我们可以用 \(\text{dfs}\) 来建图:

void build(int XX,int YY,int x,int y){
if(mark[x][y]) return ;
mark[x][y]=1;
for(int i=0;i<8;i++){
int xx=x+X[i],yy=y+Y[i];
if(xx<1||xx>n||yy<1||yy>m||mark[xx][yy]) continue;
if(a[xx][yy]==1) build(XX,YY,xx,yy);
else if(a[xx][yy]!=2) mark[xx][yy]=1,e[XX][YY].push_back({xx,yy});
}
}
int main(){
......
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(a[i][j]!=0&&a[i][j]!=3) continue;
for(int o=1;o<=n;o++) for(int p=1;p<=m;p++) mark[o][p]=0;
build(i,j,i,j);
}
}
......
}

需要注意的几个细节:

  1. 每一个 03 都应该作为起点去跑一次,并且跑之前要把 \(mark\) 清空。
  2. 每次 \(\text{dfs}\) 要把起点传入,因为走到莲叶再往外拓展时边还是连到起点上的,并不是连到前一个走到的点上。原因上面已经讲了。(笔者因为这个错误调了好久 qwq)
  3. 每次搜到一个点或连上一个点都需要将其标记掉,否则路径数可能变多(然而只 WA 了两个点?)

最短路计数

关于SPFA,他还没完全s!

在部分题中,SPFA 还是很实用的。

建好图,本题就是较常规的最短路计数,按着板子写就好了,没有什么特别的。

初始 \(cnt[sx][sy]=1\)(起点),然后只需要在普通最短路松弛操作后加这行东西就好了:

if(dis[tmp.x][tmp.y]==dis[k.x][k.y]+1){
cnt[tmp.x][tmp.y]+=cnt[k.x][k.y];
}

至于为什么很好理解,不多赘述。

最后统计答案时有一个注意点,就是我们计算的最短路是包括走到终点的一步的,而题目要求的是需要布置莲叶的数量,不包括终点,所以输出第一个数应该是 \(dis[gx][gy]-1\) 。

还有,最短路数量会爆 \(\text{int}\) ,\(cnt\) 数组记得开 \(\text{long long}\) 。

完整代码

#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
int n,m,a[55][55],dis[55][55],sx,sy,gx,gy;
long long cnt[55][55];
int X[8]={1,1,-1,-1,2,2,-2,-2},Y[8]={2,-2,2,-2,1,-1,1,-1};
bool vis[55][55],mark[55][55];
int kkk;
struct node{
int x,y;
};
vector<node> e[55][55];
queue<node> q;
void build(int XX,int YY,int x,int y){
if(mark[x][y]) return ;
mark[x][y]=1;
for(int i=0;i<8;i++){
int xx=x+X[i],yy=y+Y[i];
if(xx<1||xx>n||yy<1||yy>m||mark[xx][yy]) continue;
if(a[xx][yy]==1) build(XX,YY,xx,yy);
else if(a[xx][yy]!=2) mark[xx][yy]=1,e[XX][YY].push_back({xx,yy});
}
}
void spfa(int sx,int sy){
for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) dis[i][j]=1e9;
dis[sx][sy]=0,vis[sx][sy]=1,cnt[sx][sy]=1;
q.push({sx,sy});
while(q.size()){
node k=q.front();q.pop();
vis[k.x][k.y]=0;
for(int i=0;i<e[k.x][k.y].size();i++){
node tmp=e[k.x][k.y][i];
if(dis[tmp.x][tmp.y]>dis[k.x][k.y]+1){
dis[tmp.x][tmp.y]=dis[k.x][k.y]+1;
if(!vis[tmp.x][tmp.y]){
vis[tmp.x][tmp.y]=1;
q.push(tmp);
}
}
if(dis[tmp.x][tmp.y]==dis[k.x][k.y]+1){
cnt[tmp.x][tmp.y]+=cnt[k.x][k.y];
}
}
}
}
signed main(){
IOS;cin.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>a[i][j];
if(a[i][j]==3) sx=i,sy=j;
if(a[i][j]==4) gx=i,gy=j;
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(a[i][j]!=0&&a[i][j]!=3) continue;
for(int o=1;o<=n;o++) for(int p=1;p<=m;p++) mark[o][p]=0;
build(i,j,i,j);
}
}
spfa(sx,sy);
if(dis[gx][gy]!=1e9) cout<<dis[gx][gy]-1<<endl<<cnt[gx][gy];
else cout<<-1;
return 0;
}

【笔记】P1606 [USACO07FEB]Lilypad Pond G 及相关的更多相关文章

  1. [USACO07FEB] Lilypad Pond

    https://www.luogu.org/problem/show?pid=1606 题目描述 FJ has installed a beautiful pond for his cows' aes ...

  2. bzoj1698 / P1606 [USACO07FEB]白银莲花池Lilypad Pond

    P1606 [USACO07FEB]白银莲花池Lilypad Pond 转化为最短路求解 放置莲花的方法如果直接算会有重复情况. 于是我们可以先预处理和已有莲花之间直接互相可达的点,将它们连边(对,忽 ...

  3. 最短路【洛谷P1606】 [USACO07FEB]荷叶塘Lilypad Pond

    P1606 [USACO07FEB]荷叶塘Lilypad Pond 为了让奶牛们娱乐和锻炼,农夫约翰建造了一个美丽的池塘.这个长方形的池子被分成了M行N列个方格(1≤M,N≤30).一些格子是坚固得令 ...

  4. 洛谷 P1606 [USACO07FEB]荷叶塘Lilypad Pond 解题报告

    P1606 [USACO07FEB]荷叶塘Lilypad Pond 题目描述 FJ has installed a beautiful pond for his cows' aesthetic enj ...

  5. P1606 [USACO07FEB]荷叶塘Lilypad Pond(最短路计数)

    P1606 [USACO07FEB]荷叶塘Lilypad Pond 题目描述 FJ has installed a beautiful pond for his cows' aesthetic enj ...

  6. BZOJ 1632: [Usaco2007 Feb]Lilypad Pond

    题目 1632: [Usaco2007 Feb]Lilypad Pond Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 390  Solved: 109[ ...

  7. 1632: [Usaco2007 Feb]Lilypad Pond

    1632: [Usaco2007 Feb]Lilypad Pond Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 404  Solved: 118[Sub ...

  8. Android Studio 学习笔记(一)环境搭建、文件目录等相关说明

    Android Studio 学习笔记(一)环境搭建.文件目录等相关说明 引入 对APP开发而言,Android和iOS是两大主流开发平台,其中区别在于 Android用java语言,用Android ...

  9. 【luogu P1606 [USACO07FEB]荷叶塘Lilypad Pond】 题解

    题目链接:https://www.luogu.org/problemnew/show/P1606 这个题..第一问很好想,但是第二问,如果要跑最短路计数的话,零边权的花怎么办? 不如这样想,如果这个点 ...

随机推荐

  1. HC32L110(三) HC32L110的GCC工具链和VSCode开发环境

    目录 HC32L110(一) HC32L110芯片介绍和Win10下的烧录 HC32L110(二) HC32L110在Ubuntu下的烧录 HC32L110(三) HC32L110的GCC工具链和VS ...

  2. 不想当Window的Dialog不是一个好Modal,弹窗翻身记

    弹窗是我们熟视无睹的一种交互方式,经常用到,但从没好好想过这种交互行为背后的意义... 弹窗是Windows的灵魂 Windows的灵魂是什么?当然是Window,当方便快捷的多窗口进入人们视野的时候 ...

  3. Java 流处理之收集器

    Java 流(Stream)处理操作完成之后,我们可以收集这个流中的元素,使之汇聚成一个最终结果.这个结果可以是一个对象,也可以是一个集合,甚至可以是一个基本类型数据. 以记录 Record 为例: ...

  4. 坚守自主创新,璞华HawkEye IETM系统惠及国计民生

    可上九天揽月,可下五洋捉鳖,这是我们很多年的梦想.而要实现这样的梦想,不仅需要安全可靠的技术装备,还需要让这些技术装备处于良好的维保状态.于是,作为装备维保过程中必须的知识创作.管理.发布.浏览工具, ...

  5. Windows客户端DNS工作原理

    通常大家对Windows客户端DNS的配置存在多个误区. 误区一,配置1个内网DNS,1个外网DNS.解析内网的时候用内网DNS,解析外网的时候用外网. 电脑怎么知道哪个是内网?哪个是外网?我们内部的 ...

  6. 【学习笔记】卷积神经网络 (CNN )

    前言 对于卷积神经网络(cnn)这一章不打算做数学方面深入了解,所以只是大致熟悉了一下原理和流程,了解了一些基本概念,所以只是做出了一些总结性的笔记. 感谢B站的视频 https://www.bili ...

  7. Pod原理

    Pod 是 Kubernetes 集群中最基本的调度单元,我们平时在集群中部署的应用都是以 Pod 为单位的,而并不是我们熟知的容器,这样设计的目的是什么呢?为何不直接使用容器呢? 为什么需要 Pod ...

  8. 利用 Nginx 反向代理搭建本地 yum 服务器

    在政府,医院等单位有网络安全要求,对内外网进行物理隔离,然而内网主机无法访问互联网下载安装包,通过Nginx 反向代理搭建本地yum服务器实现内网主机安装包下载. Centos 8.2 部署 Ngin ...

  9. My life of Honker Security Commando

    红客突击队 && 红客突击分队 红客突击队,于2019年,由队长k龙联合国内多位顶尖高校研究生牵头成立.其团队从成立至今多次参加国际网络安全竞赛并取得良好成绩,积累了丰富的竞赛经验.团 ...

  10. OpenJudge 1.5.35:求出e的值

    35:求出e的值 总时间限制:1000ms 内存限制:65536kB 描述 利用公式e = 1 + 1/1! + 1/2! + 1/3! + ... + 1/n! 求e . 输入 输入只有一行,该行包 ...