\(\\\)

\(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. 百度语音识别API初探

    近期想做个东西把大段对话转成文字.用语音输入法太慢,所以想到看有没有现成的API,网上一搜,基本就是百度和讯飞. 这里先看百度的 笔者使用的是Java版本号的 下载地址:http://bos.nj.b ...

  2. Android怎样监听蓝牙耳机的按键事件

    Android怎样监听蓝牙耳机的按键事件 写在前面: 直接想要代码非常easy,你直接把滚动栏拉到最底端就能够看到.假设想要十分地了解为什么,那就依照我规划的一步一步来理解.下面測试环境以手头上有的「 ...

  3. zipfile zip

    Python模块学习:zipfile zip文件操作 2015/05/27 · 系列教程 · zipfile 分享到:3 原文出处: DarkBull    最近在写一个网络客户端下载程序,用于下载服 ...

  4. C Language Study - gets , getchar &amp; scanf

    慢慢的发现C语言功底是如此的薄弱,被这几个字符输入函数搞糊涂了又~~ 来,再来忧伤一次吧~ 那么.我们从scanf開始: 假如说你要将一串字符输入到一字符数组里,例如以下面程序, char a[2]; ...

  5. PHP在浏览器上跟踪调试的方法以及使用ChromePhp、FirePHP的简介

    之前用ThinkPHP时发现有个 trace 函数能够跟踪调试,感觉非常有意思.网上搜索了下类似的东西.发现了 ChromePhp ,曾经没想过这样来调试 PHP 程序.感觉非常方便,非常实用. Th ...

  6. HDU 1018 Big Number (log函数求数的位数)

    Problem Description In many applications very large integers numbers are required. Some of these app ...

  7. SGU 261. Discrete Roots (N次剩余)

    N次剩余 题目:http://acm.sgu.ru/problem.php? contest=0&problem=261 题意:给定n,a,p 求出x^n ≡ a(mod p)在模p意义下的全 ...

  8. java SocketChannel and ServerSocketChannel

    1 SocketChannel 1.1 打开一个SocketChannel SocketChannel socketChannel = SocketChannel.open(); socketChan ...

  9. HDU 1505 City Game(DP)

    City Game Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total ...

  10. MATLAB——matlab特殊符号表【转载】

    链接来源: matlab特殊符号表 http://blog.sina.com.cn/s/blog_4a09187801014xg9.html Character Sequence Symbol Cha ...