\(\\\)

\(Description\)


一张\(N\times M\)的网格,已知起点和终点,其中有一些地方是落脚点,有一些地方是空地,还有一些地方是坏点。

现在要从起点到终点,每次移动走日字\((\)横一纵二或横二纵一\()\),其中只能经过起点、终点、落脚点。

现在可以开发任意个数的空地变为落脚点,问找到合法路径最少需要开发多少个空地,在满足第一个条件下最少移动多少步,在满足前两个条件下有多少条不同的路径。

  • \(N,M\in [1,30]\)

\(\\\)

\(Solution\)


被上一个题干蒙直接\(NC\)......我还说Silver咋比Gold还难

这题.......仔细读题之后错觉是\(Gold\)那题再加上一层限制的最短路,后来发现不是.......

仔细读题,注意这次的方案数不再是放置落脚点的方案,而是路径数。

那么我们就不必考虑选择不同原有落脚点导致方案同构的尴尬情况了,直接将每一个点向一步可以到达的点建边,如果是从空地向外建边代价为\(1\),其他为\(0\)即可。

最短路计数时有双层限制,注意讨论更新的情况。

\(\\\)

\(Code\)


#include<cmath>
#include<queue>
#include<cctype>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define N 50
#define M 60010
#define R register
#define gc getchar
#define inf 9000000000000000ll
using namespace std;
typedef long long ll; inline int rd(){
int x=0; bool f=0; char c=gc();
while(!isdigit(c)){if(c=='-')f=1;c=gc();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=gc();}
return f?-x:x;
} bool vis[N*N]; const int dx[8]={1,1,-1,-1,2,2,-2,-2}; const int dy[8]={2,-2,2,-2,1,-1,1,-1}; ll ts[N*N],stp[N*N],dis[N*N];
int n,m,s,t,tot,cnt,num[N][N],mp[N][N],hd[N*N]; struct edge{int w,to,nxt;}e[M<<1]; inline void add(int u,int v,int w){
e[++tot].to=v; e[tot].w=w;
e[tot].nxt=hd[u]; hd[u]=tot;
} inline void make(int ux,int uy){
for(R int i=0,nx,ny;i<8;++i){
nx=ux+dx[i]; ny=uy+dy[i];
if(nx<1||nx>n||ny<1||ny>m) continue;
add(num[ux][uy],num[nx][ny],mp[ux][uy]==0);
}
} queue<int> q; inline void SPFA(){
memset(vis,0,sizeof(vis));
memset(stp,0x3f,sizeof(stp));
for(R int i=1;i<=cnt;++i) dis[i]=inf;
q.push(s); dis[s]=0;
ts[s]=1ll; stp[s]=0;
while(!q.empty()){
int u=q.front();
q.pop(); vis[u]=0;
for(R int i=hd[u],v;i;i=e[i].nxt)
if(dis[v=e[i].to]>dis[u]+e[i].w){
dis[v]=dis[u]+e[i].w;
stp[v]=stp[u]+1; ts[v]=ts[u];
if(!vis[v]) vis[v]=1,q.push(v);
}
else if(dis[v]==dis[u]+e[i].w&&stp[v]>stp[u]+1){
stp[v]=stp[u]+1; ts[v]=ts[u];
if(!vis[v]) vis[v]=1,q.push(v);
}
else if(dis[v]==dis[u]+e[i].w&&stp[v]==stp[u]+1) ts[v]+=ts[u];
}
} int main(){
n=rd(); m=rd();
for(R int i=1;i<=n;++i)
for(R int j=1;j<=m;++j){
mp[i][j]=rd();
num[i][j]=++cnt;
if(mp[i][j]==3) s=cnt;
if(mp[i][j]==4) t=cnt;
}
for(R int i=1;i<=n;++i)
for(R int j=1;j<=m;++j)
if(mp[i][j]!=2) make(i,j);
SPFA();
if(dis[t]<inf) printf("%lld\n%lld\n%lld\n",dis[t],stp[t],ts[t]);
else puts("-1");
return 0;
}

[ USACO 2007 FEB ] Lilypad Pond (Silver)的更多相关文章

  1. [ USACO 2007 FEB ] Lilypad Pond (Gold)

    \(\\\) \(Description\) 一张\(N\times M\)的网格,已知起点和终点,其中有一些地方是落脚点,有一些地方是空地,还有一些地方是坏点. 现在要从起点到终点,每次移动走日字\ ...

  2. 1632: [Usaco2007 Feb]Lilypad Pond

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

  3. BZOJ 1632: [Usaco2007 Feb]Lilypad Pond

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

  4. 「BZOJ 1698」「USACO 2007 Feb」Lilypad Pond 荷叶池塘「最短路」

    题解 从一个点P可以跳到另一个点Q,如果Q是水这条边就是1,如果Q是荷叶这条边权值是0.可以跑最短路并计数 问题是边权为0的最短路计数没有意义(只是荷叶的跳法不同),所以我们两个能通过荷叶间接连通的点 ...

  5. bzoj1632 [Usaco2007 Feb]Lilypad Pond

    Description Farmer John 建造了一个美丽的池塘,用于让他的牛们审美和锻炼.这个长方形的池子被分割成了 M 行和 N 列( 1 ≤ M ≤ 30 ; 1 ≤ N ≤ 30 ) 正方 ...

  6. BZOJ1632: [Usaco2007 Feb]Lilypad Pond SPFA+最短路计数

    Description 为了让奶牛们娱乐和锻炼,农夫约翰建造了一个美丽的池塘.这个长方形的池子被分成了M行N列个方格(1≤M,N≤30).一些格子是坚固得令人惊讶的莲花,还有一些格子是岩石,其余的只是 ...

  7. 【BZOJ】1632: [Usaco2007 Feb]Lilypad Pond(bfs)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1632 我简直是个sb... ... bfs都不会写.. 算方案还用2个bfs! 都不会整合到一个! ...

  8. BZOJ 1632 [Usaco2007 Feb]Lilypad Pond:spfa【同时更新:经过边的数量最小】【路径数量】

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1632 题意: 有一个n*m的池塘.0代表水,1代表荷花,2代表岩石,3代表起点,4代表终点 ...

  9. BZOJ1698: [Usaco2007 Feb]Lilypad Pond 荷叶池塘

    一傻逼题调了两天.. n<=30 * m<=30的地图,0表示可以放平台,1表示本来有平台,2表示不能走,3起点4终点,走路方式为象棋的日字,求:从起点走到终点,至少要放多少平台,以及放平 ...

随机推荐

  1. CentOS 7 es搭建测试

    搭建本地yum repo pass 指定特定repo 安装,比如安装wget.(指定特定repo 是为了从最快的repo安装) yum --disablerepo=\* --enablerepo=os ...

  2. java代码判断文件类型(判断文件后缀名)

    1.两点需要注意 1.string.spilt("\\.")分割字符串成子字符串数组,以“.”分割,必须写成string.spilt("\\.")的方式,不能写 ...

  3. 我的arcgis培训照片7

    来自:http://www.cioiot.com/successview-553-1.html

  4. [转]chrome 的devtools 中setting 开启workspace , 也有点用处。不是很大

    转载的,原文: http://wiki.jikexueyuan.com/project/chrome-devtools/saving-changes-with-workspaces.html ---- ...

  5. PLC基础入门

    PLC编程入门基础技术知识学习 2016-06-27  xjp7879  摘自 电工技术知...     第一章  可编程控制器简介 可编程序控制器,英文称Programmable Controlle ...

  6. day2-搭建hdfs分布式集群

    1.搭建hdfs分布式集群 4.1 hdfs集群组成结构: 4.2 安装hdfs集群的具体步骤: 一.首先需要准备N台linux服务器 学习阶段,用虚拟机即可! 先准备4台虚拟机:1个namenode ...

  7. MYSQL入库常用PHP函数

    addslashes   addslashes() 函数在指定的预定义字符前添加反斜杠.这些字符是单引号(').双引号(").反斜线(\)与NUL(NULL字符).   stripslash ...

  8. 2016/1/22 3,将id为005的对象从集合中移除

    package shuzu; public class Emp { private String id; private String name; public Emp(String id, Stri ...

  9. 简易 DBUtil 封装

    Dao包结构图: 1.首先连接数据库 package com.util.db; import java.sql.Connection; import java.sql.DriverManager; i ...

  10. hdoj--1254--推箱子(bfs好题)

     推箱子 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Sub ...