题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1632

题意:

  有一个n*m的池塘。0代表水,1代表荷花,2代表岩石,3代表起点,4代表终点。

  Bessie在练芭蕾舞,她要从起点跳到终点去。

  她只能走“日”字形,并且只能跳到荷花上。

  荷花不能长在岩石上。

  问你:

    (1)至少要再添加多少个荷花,才能使Bessie可以跳到终点。

    (2)在(1)的前提下,让Bessie跳到终点的步数最小,并输出。

    (3)在(1)(2)条件下的路径条数。

题解:

  方便起见,对于每个点(x,y)可以表示成x*m+y的形式,即平面上的点在实数上的唯一映射。

  

  第一问:

    建图。

    对于每个点,到水建一条边长为1的边,到荷花建一条边长为0的边。

    跑一边spfa,第一问就出来了。

  第二问:

    在spfa中更新dis的时候,分两种情况:

      (1)dis[dest]==-1 || dis[dest]>dis[now]+len

        此时dis被更新,相应的step[dest]一定要变成step[now]+1。

      (2)dis[dest]==dis[now]+len

        dis未被更新,但step有可能更优,step[dest] = min(step[dest], step[now]+1)

  第三问:

    在前两问都不变的情况下,才有可能 cnt[dest] += cnt[now]。

    否则cnt[dest] = cnt[now]

AC Code:

 #include <iostream>
#include <stdio.h>
#include <string.h>
#include <vector>
#include <queue>
#define MAX_N 35
#define MAX_P 905 using namespace std; const int dx[]={-,-,-,-,,,,};
const int dy[]={-,,-,,-,,-,}; struct Edge
{
int dest;
int len;
Edge(int _dest,int _len)
{
dest=_dest;
len=_len;
}
Edge(){}
}; int n,m;
int start,over;
int dis[MAX_P];
int step[MAX_P];
long long cnt[MAX_P];
int a[MAX_N][MAX_N];
bool vis[MAX_P];
vector<Edge> edge[MAX_P];
queue<int> q; void read()
{
cin>>n>>m;
for(int i=;i<n;i++)
{
for(int j=;j<m;j++)
{
cin>>a[i][j];
if(a[i][j]==) start=i*m+j;
if(a[i][j]==) over=i*m+j;
}
}
} inline bool is_legal(int x,int y)
{
return x>= && x<n && y>= && y<m;
} void build_graph()
{
for(int i=;i<n;i++)
{
for(int j=;j<m;j++)
{
for(int k=;k<;k++)
{
int x=i+dx[k];
int y=j+dy[k];
if(is_legal(x,y) && a[x][y]!=)
{
edge[i*m+j].push_back(Edge(x*m+y,a[x][y]==));
}
}
}
}
} int get_front()
{
int now=q.front();
q.pop();
vis[now]=false;
return now;
} void insert(int now)
{
if(vis[now]) return;
q.push(now);
vis[now]=true;
} void spfa(int start)
{
memset(dis,-,sizeof(dis));
memset(step,0x3f,sizeof(step));
memset(cnt,,sizeof(cnt));
memset(vis,false,sizeof(vis));
insert(start);
dis[start]=;
step[start]=;
cnt[start]=;
while(!q.empty())
{
int now=get_front();
for(int i=;i<edge[now].size();i++)
{
Edge temp=edge[now][i];
if(dis[temp.dest]==- || dis[temp.dest]>dis[now]+temp.len)
{
dis[temp.dest]=dis[now]+temp.len;
step[temp.dest]=step[now]+;
cnt[temp.dest]=cnt[now];
insert(temp.dest);
}
else if(dis[temp.dest]==dis[now]+temp.len)
{
if(step[temp.dest]>step[now]+)
{
step[temp.dest]=step[now]+;
cnt[temp.dest]=cnt[now];
insert(temp.dest);
}
else if(step[temp.dest]==step[now]+)
{
cnt[temp.dest]+=cnt[now];
insert(temp.dest);
}
}
}
}
} void solve()
{
build_graph();
spfa(start);
} void print()
{
cout<<dis[over]<<endl;
if(dis[over]!=-)
{
cout<<step[over]<<endl;
cout<<cnt[over]<<endl;
}
} int main()
{
read();
solve();
print();
}

BZOJ 1632 [Usaco2007 Feb]Lilypad Pond:spfa【同时更新:经过边的数量最小】【路径数量】的更多相关文章

  1. BZOJ 1632: [Usaco2007 Feb]Lilypad Pond

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

  2. bzoj 1632: [Usaco2007 Feb]Lilypad Pond【bfs】

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

  3. 1632: [Usaco2007 Feb]Lilypad Pond

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

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

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

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

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

  6. bzoj1632 [Usaco2007 Feb]Lilypad Pond

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

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

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

  8. BZOJ 1631: [Usaco2007 Feb]Cow Party( 最短路 )

    这道题和蔡大神出的今年STOI初中组的第二题几乎一模一样... 先跑一遍最短路 , 再把所有边反向 , 再跑一遍 , 所有点两次相加的最大值即为answer --------------------- ...

  9. BZOJ 1631: [Usaco2007 Feb]Cow Party

    题目 1631: [Usaco2007 Feb]Cow Party Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 491  Solved: 362[Sub ...

随机推荐

  1. 多核服务器的JVM优化选项(转载)

    原文链接 现在多核CPU是主流.利用多核技术,可以有效发挥硬件的能力,提升吞吐量,对于Java程序,可以实现并发垃圾收集.但是Java利用多核技术也带来了一些问题,主要是多线程共享内存引起了.目前内存 ...

  2. BZOJ1001[BeiJing2006]狼抓兔子最小割網絡流

    Description 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的, 而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一 ...

  3. NFC模组,开发NFC功能 仅仅要几条指令的事情

    特点:实现NFC透明传输.内置NFC协议栈,支持UART串口直接读写,用于门禁能够同一时候兼容手机和卡片开门,还能实现动态密钥,读到的NFC数据自己主动串口输出,会串口就能开发NFC,不须要研究LLC ...

  4. PS 如何使用钢笔工具

    1.钢笔工具属于矢量绘图工具,其优点是可以勾画平滑的曲线,在缩放或者变形之后仍能保持平滑效果. 2.钢笔工具画出来的矢量图形称为路径,路径是矢量的路径允许是不封闭的开放状,如果把起点与终点重合绘制就可 ...

  5. Tessellation (曲面细分) Displacement Mapping (贴图置换)

    DirectX 11 Tessellation (曲面细分)-什么是 Tessellation (曲面细分) ? 它为什么可以起到如此关键的数据? 随着近期人们对 DirectX 11 的议论纷纷,你 ...

  6. 解读Unity中的CG编写Shader系列1——初识CG

    CG=C for Graphics  用于计算机图形编程的C语言超集 前提知识点: 1.CG代码必须用 CGPROGRAM ... ENDCG括起来 2.顶点着色器与片段着色器的主函数名称可任意,但须 ...

  7. C++编译错误 2001 1120

    无法解析的外部符号"symbol" 代码引用了链接器无法在库和对象文件中找到的内容(如函数.变量或标签). 该错误信息之后为错误 LNK1120. 可能的原因 : 在将托管库或 W ...

  8. C#文件操作与编程

    一:驱动器System.IO 软盘,优盘,光盘,硬盘 DriveInfo/DriveType DriveInfo:确定有关驱动器的信息:盘符,类型,可用空间 DriveType:确定DriveInfo ...

  9. __del__删除方法

    class dog: def __del__(self): print("删除机制被调用了...") dog1 = dog() del dog1 #在这里是先删除掉了,所以就去上面 ...

  10. Windows下利用CMake和VS2013编译OpenCV

    转载自:http://www.chengxulvtu.com/2014/03/19/windows_build-opencv-with-cmake-and-vs2013.html   获取OpenCV ...