一傻逼题调了两天。。

n<=30 * m<=30的地图,0表示可以放平台,1表示本来有平台,2表示不能走,3起点4终点,走路方式为象棋的日字,求:从起点走到终点,至少要放多少平台,以及放平台的方案数,无解-1。

方法一:其实能走直接平台的就可以直接走来走去,也就是算一个联通块。类似于tarjan,先把一大块缩成一点,然后连边走最短路。

错误!存在边权为0的边,会导致统计方案出现重复。比如:

圆圈走到三角形,直接走和绕一圈是一样的,但算了两次。

方法二:把0边去掉就行了。由于数据小,开个数组[a][b][c][d]表示a,b到c,d是否能通过填一块到达,这个数组只需对每个点做一次搜索就能出来。最后就是最短路啦。

不过边权为1,谁最短路会写迪杰呢?肯定bfs啦!

 #include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
//#include<iostream>
using namespace std; int n,m;
int a[][],can[][][][];
#define maxn 1011
#define maxm 10011
struct Edge{int tx,ty,next;}edge[maxn*maxn];int first[][],le=;
#define LL long long
void in(int sx,int sy,int tx,int ty)
{
Edge &e=edge[le];
e.tx=tx;e.ty=ty;
e.next=first[sx][sy];
first[sx][sy]=le++;
}
int nx,ny;
const int dx[]={,,,,-,-,-,-},dy[]={,-,,-,,-,,-};
bool vis[][];
void dfs(int x,int y)
{
vis[x][y]=;
for (int i=;i<;i++)
{
const int xx=x+dx[i],yy=y+dy[i];
if (xx< || xx>n || yy< || yy>m || can[nx][ny][xx][yy]
|| a[xx][yy]== || vis[xx][yy]) continue;
if (a[xx][yy]== || a[xx][yy]==)
{
can[nx][ny][xx][yy]=;
continue;
}
dfs(xx,yy);
}
}
const int inf=0x3f3f3f3f;
int dis[][];LL way[][];
struct qnode{int x,y;}q[maxn];int head,tail;
void bfs(int sx,int sy)
{
head=;tail=;q[].x=sx;q[].y=sy;
for (int i=;i<=n;i++)
for (int j=;j<=m;j++)
dis[i][j]=inf;
dis[sx][sy]=;way[sx][sy]=;
while (head!=tail)
{
const int nx=q[head].x,ny=q[head++].y;
for (int i=first[nx][ny];i;i=edge[i].next)
{
const Edge &e=edge[i];
if (dis[e.tx][e.ty]>dis[nx][ny]+)
{
dis[e.tx][e.ty]=dis[nx][ny]+;
way[e.tx][e.ty]=way[nx][ny];
q[tail].x=e.tx,q[tail++].y=e.ty;
}
else if (dis[e.tx][e.ty]==dis[nx][ny]+)
way[e.tx][e.ty]+=way[nx][ny];
}
}
}
int main()
{
scanf("%d%d",&n,&m);
int sx,sy,tx,ty;
for (int i=;i<=n;i++)
for (int j=;j<=m;j++)
{
scanf("%d",&a[i][j]);
if (a[i][j]==) sx=i,sy=j;
if (a[i][j]==) tx=i,ty=j;
}
for (int i=;i<=n;i++)
for (int j=;j<=m;j++)
{
memset(can[i][j],,sizeof(can[i][j]));
memset(vis,,sizeof(vis));
if (a[i][j]==) continue;
nx=i;ny=j;
dfs(i,j);
}
memset(first,,sizeof(first));
for (int i=;i<=n;i++)
for (int j=;j<=m;j++)
for (int k=;k<=n;k++)
for (int l=;l<=m;l++)
{
if (can[i][j][k][l])
{
in(i,j,k,l);
}
}
bfs(sx,sy);
if (dis[tx][ty]==inf) puts("-1");
else printf("%d\n%lld\n",dis[tx][ty]-,way[tx][ty]);
return ;
}

BZOJ1698: [Usaco2007 Feb]Lilypad Pond 荷叶池塘的更多相关文章

  1. BZOJ 1632: [Usaco2007 Feb]Lilypad Pond

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

  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 1698」「USACO 2007 Feb」Lilypad Pond 荷叶池塘「最短路」

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

  4. bzoj1632 [Usaco2007 Feb]Lilypad Pond

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

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

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

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

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

  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【bfs】

    直接bfs,在过程中更新方案数即可 #include<iostream> #include<cstdio> #include<queue> using namesp ...

  9. [ USACO 2007 FEB ] Lilypad Pond (Silver)

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

随机推荐

  1. iOS开发中的HTML解析

    在进行解析前,先将下面的第三方类添加到工程中: 添加以上三个类必须添加一个库,这个库是:libxml2.2.dylib. 还需要设置一些路径参数这个路径的设置,在 targets中,在build se ...

  2. 原创:mysql下载 实战 最强最全的无脑白痴版 给小白的爱

  3. c语言 预处理的使用 宏展开下的#,##

    1. #include   包含头文件 2.define 宏定义(可以理解为替换,不进行语法检查) 写法 #define 宏名 宏体  加括号 #define ABC (5+3) #define AB ...

  4. EXECUTE - 执行一个准备好的查询

    SYNOPSIS EXECUTE plan_name [ (parameter [, ...] ) ] DESCRIPTION 描述 EXECUTE 用于执行一个前面准备好的语句. 因为一个准备好的查 ...

  5. billu_b0x靶场刷题

    https://www.vulnhub.com/ 里面有很多安全环境,只要下载相关镜像,在虚拟机上面搭建运行就可以练习对应靶场了. 第一步.信息收集 nmap扫描内网开放80端口的存活主机  nmap ...

  6. 摄像头调用代码 笔记本的话,本身有一个摄像头,由于用的usb摄像头,需要把笔记本的摄像头禁用后,再使用

    摄像头调用代码 笔记本的话,本身有一个摄像头,由于用的usb摄像头,需要把笔记本的摄像头禁用后,再使用 <!DOCTYPE html> <html lang="en&quo ...

  7. redis基础一_常用指令

    # Redis configuration file example. # # Note that in order to read the configuration file, Redis mus ...

  8. PHP05 PHP语言基础

    学习要点 初识PHP 基础语法 变量 常量 运算符 表达式 学习目标 掌握PHP基础语法 掌握PHP变量 掌握PHP常量 掌握PHP表达式 掌握PHP运算符 初识PHP 第一个PHP程序 编写代码 1 ...

  9. sublime中使用markdown并实时编辑

    1.需求 想在sublime中编辑.md文件 2.步骤 找到菜单栏: 快捷键,shift + command + p,选择 Package Control:Install Package, 没有找到P ...

  10. koa源码解读

    koa是有express原班人马打造的基于node.js的下一代web开发框架.koa 1.0使用generator实现异步,相比于回调简单和优雅和不少.koa团队并没有止步于koa 1.0, 随着n ...