这个题其实算是个最短路计数,建图的直观思想很简单,但是很显然有一个地方没法处理,就是有的时候通过两条路走到同一个地方的话方案数会计算两次。我们发现加上原有的莲花就很难处理,会计算重复。我们要想办法避免这种情况,一开始想联通块,其实已经差不多了,就是把已经有的互相联通的看成一块,然后和水暴力连边,最后跑裸的最短路就行了。(原来有0边就不能直接跑最短路计数啊)。

题干:

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

贝西正在练习芭蕾舞,她站在一朵莲花上,想跳到另一朵莲花上去,她只能从一朵莲花跳到另一朵莲花上,既不能跳到水里,也不能跳到岩石上。

贝西的舞步很像象棋中的马步:每次总是先横向移动一格,再纵向移动两格,或先纵向移动两格,再横向移动一格。最多时,贝西会有八个移动方向可供选择。

约翰一直在观看贝西的芭蕾练习,发现她有时候不能跳到终点,因为中间缺了一些荷叶。于是他想要添加几朵莲花来帮助贝西完成任务。一贯节俭的约翰只想添加最少数量的莲花。当然,莲花不能放在石头上。

请帮助约翰确定必须要添加的莲花的最少数量,以及有多少种放置这些莲花的方法。

代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
#define duke(i,a,n) for(register int i = a;i <= n;++i)
#define lv(i,a,n) for(register int i = a;i >= n;--i)
#define clean(a) memset(a,0,sizeof(a))
const int INF = ;
typedef long long ll;
typedef double db;
template <class T>
void read(T &x)
{
char c;
bool op = ;
while(c = getchar(), c < '' || c > '')
if(c == '-') op = ;
x = c - '';
while(c = getchar(), c >= '' && c <= '')
x = x * + c - '';
if(op) x = -x;
}
template <class T>
void write(T x)
{
if(x < ) putchar('-'), x = -x;
if(x >= ) write(x / );
putchar('' + x % );
}
struct node
{
int l,r,nxt;
}a[];
int lst[],len = ;
int n,m,fx,fy,sx,sy;
int id[][],mp[][];
int vis[][];
const int dx[]={,,-,-,,,-,-};
const int dy[]={,,,,-,-,-,-};
int dis[];
ll to[];
int used[];
void add(int x,int y)
{
a[++len].l = x;
a[len].r = y;
a[len].nxt = lst[x];
lst[x] = len;
}
void dfs(int idx,int x,int y)
{
if(vis[x][y] == ) return;
vis[x][y] = ;
// cout<<idx<<" "<<x<<" "<<y<<endl;
for(int i = ;i < ;i++)
{
int nx = x + dx[i];
int ny = y + dy[i];
if(nx > n || ny > m || nx < || ny < || vis[nx][ny] == ) continue;
// cout<<nx<<" "<<ny<<endl;
if(mp[nx][ny] == ) dfs(idx,nx,ny);
else if(mp[nx][ny] != )
{
vis[nx][ny] = ;
// cout<<idx<<" "<<id[nx][ny]<<endl;
add(idx,id[nx][ny]);
}
}
}
void spfa()
{
int s = id[sx][sy];
int t = id[fx][fy];
queue <int> q;
duke(i,,n * m)
{
dis[i] = INF;
}
dis[s] = ;to[s] = 1LL;
q.push(s);
while(!q.empty())
{
int now = q.front();
q.pop();
used[now] = ;
for(int k = lst[now];k;k = a[k].nxt)
{
int y = a[k].r;
if(dis[y] > dis[now] + )
{
dis[y] = dis[now] + ;
to[y] = to[now];
if(used[y] == )
{
q.push(y);
used[y] = ;
}
}
else if(dis[y] == dis[now] + )
to[y] += to[now];
}
}
if(dis[t] < INF) printf("%d\n%lld\n",dis[t] - ,to[t]);
else
printf("-1\n");
}
int main()
{
read(n);read(m);
duke(i,,n)
{
duke(j,,m)
{
read(mp[i][j]);
id[i][j] = (i - ) * m + j;
if(mp[i][j] == )
{
sx = i;
sy = j;
}
if(mp[i][j] == )
{
fx = i;
fy = j;
}
}
}
duke(i,,n)
{
duke(j,,m)
{
if(!mp[i][j] || mp[i][j] == )
{
// cout<<i<<" "<<j<<endl;
clean(vis);
dfs(id[i][j],i,j);
}
}
}
spfa();
return ;
}

P1606 [USACO07FEB]白银莲花池Lilypad Pond的更多相关文章

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

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

  2. Luogu 1606 [USACO07FEB]白银莲花池Lilypad Pond

    感觉应当挺简单的,但是弄了好久……菜死了 如果不考虑那些为$1$的点,直接跑个最短路计数就好了,但是我们现在有一些边可以不用付出代价,那么只要在连边的时候先预处理搜一下就好了. 原来的想法是拆点,但是 ...

  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. 【luogu P1606 [USACO07FEB]荷叶塘Lilypad Pond】 题解

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

  9. [洛谷P1606] [USACO07FEB] 荷叶塘Lilypad Pond

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

随机推荐

  1. 日常开发需要掌握的Git命令

    本人待的两家公司,一直都是用的SVN,Git我只是自己私下学习和开发小项目的时候用过,工作一直没有使用过,但还是要学的... Git是最好的分布式版本控制系统 工作流程 SVN和Git的区别 SVN是 ...

  2. ThinkPHP---thinkphp文件加载

    [一]文件加载在ThinkPHP里提供了三种方式 实际开发里,文件加载方式一般以第一种为主(通过函数库形式自动加载,此时我们仅仅需要定义文件和函数) (1)函数库形式加载 函数库分3种级别,系统函数库 ...

  3. position的简单用法实例 ----- 方框里图片放对应的角标

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <hea ...

  4. 抓取猫眼电影top100的正则、bs4、pyquery、xpath实现方法

    import requests import re import json import time from bs4 import BeautifulSoup from pyquery import ...

  5. JavaScript--小白入门篇3

    一.函数 1.1 初步认识函数 1 <script type="text/javascript"> 2 console.log("你好"); 3 s ...

  6. (C/C++学习)19.单目标遗传算法的C程序实现

    说明:在学习生活中,经常会遇到各种各样的最优问题,其中最常见的就是求某个多维(多个自变量)函数在各个自变量各取何值时的最大值或最小值:例如求函数 f(x) = (x-5)2+(y-6)2+(z-7)2 ...

  7. [USACO06JAN] 牛的舞会 The Cow Prom

    题目描述 The N (2 <= N <= 10,000) cows are so excited: it's prom night! They are dressed in their ...

  8. centOS目录结构介绍

    Linux / CentOS目录结构 /: 根目录,一般根目录下只存放目录,不要存放文件,/etc./bin./dev./lib./sbin应该和根目录放置在一个分区中 /bin:/usr/bin: ...

  9. Extract local angle of attack on wind turbine blades

    Extract local angle of attack on wind turbine blades Table of Contents 1. Extract local angle of att ...

  10. 离职 mark

    昨天(2019 年 5 月 17 日),从 离职. 从 2018 年 7 月 14 日早 10 点余分到 2019 年 5 月 17 日早 10 点余分,一共 308 天整.这就是我出学校的第一份工作 ...