bzoj 1698: [Usaco2007 Feb]Lilypad Pond 荷叶池塘 spfa+bfs
2016-11-03 19:54
411 查看
题目
Description为了便于牛们欣赏和锻炼,农夫JOHN在他的农场上新添加了一个美丽的池塘。 JOHN的池塘是一个长方形,他已经把它划分成了M行N列的小正方行 (1 <= M <= 30; 1 <= N <= 30). 某些正方行里是石头,另外一些则是特别结实的荷叶,其余则只有清水。 为了锻炼,Bessie想从一片荷叶跳到另外一片。她的每一次跳跃都是一个象棋中的马步:两行一列或一行两列。 JOHN看到了Bessie并且发现有时Bessie没有办法达到她的目标荷叶。他准备添加一些荷叶来让Bessie完成她的目标。当然,荷叶不能放在石头上。 帮助JOHN找出他最少要放多少片荷叶和他一共有多少种放最少片荷叶的方案。
Input
第1行: 两个整数, M 和 N。
第2~M+1行: 第i+1包含N个数,分别为第i行的N个格子的情况。 0表示格子为空,1表示有一片荷叶,2表示格子里有石头,3表示此格子是Bessie的起点,4 表示此格子是Bessie的目标。
Output
第1行: 一个数,最少情况下需要添加的荷叶数目。如果没有方案存在,输出- 1。
第2行: 一个数,达到最小值的方案总数。这个数保证不超过内设64位整数(long long/ int64)的大小。如果第一行是-1,不要输出此行。
Sample Input
4 5
1 0 0 0 0
3 0 0 0 0
0 0 2 0 0
0 0 0 4 0
输入解释:
池塘含4行5列。Bessie在第2行第1列并且想跳到第4行第4列。池塘里有1块
石头和3片荷叶。
Sample Output
2
3
输出解释:
至少需要2片荷叶。一共有三种摆法:
第4行第2列,第2行第3列
第1行第3列,第3行第2列
第1行第3列,第2行第5列
R1C2,R2C3 R1C3,R3C2 R1C3,R2C5 1 0 0 0 0 1 0 X 0 0 1 0 X 0 0 3 0 X 0 0 3 0 0 0 0 3 0 0 0 X 0 0 2 0 0 0 X 2 0 0 0 0 2 0 0 0 X 0 4 0 0 0 0 4 0 0 0 0 4 0
分析
挺有意思的题,想了一段时间才做出来。因为第一问和第二问都只是涉及到了“水”点,那么我们就试着把除了起点,终点和“水”点之外的点的影响都去掉。
那么我们可以对每个“水”点bfs出该“水”点可以通过荷叶走到哪些“水”点,然后在这两条“水”点之间连边。
那么第一问就转换成了起点到终点的最短路,第二问就转换成了起点到终点最短路径的数量。
跑一遍spfa即可。
记得开long long
代码
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #include<queue> #define N 35 #define inf 0x3f3f3f3f #define ll long long using namespace std; int cnt,tot,n,m,num ,map ,last[N*N],vis1 ,vis2[N*N],dx[8]={1,2,1,2,-1,-2,-1,-2},dy[8]={2,1,-2,-1,2,1,-2,-1},f[N*N],s,t,vis3[N*N][N*N]; ll g[N*N]; struct edge{int to,next;}e[N*10000]; struct data{int x,y;}; queue <data> q1; queue <int> q2; void addedge(int u,int v) { if (vis3[u][v]) return; vis3[u][v]=vis3[v][u]=1; e[++cnt].to=v;e[cnt].next=last[u];last[u]=cnt; e[++cnt].to=u;e[cnt].next=last[v];last[v]=cnt; } void bfs(int x,int y,int z) { memset(vis1,0,sizeof(vis1)); vis1[x][y]=1; data u; u.x=x;u.y=y; q1.push(u); while (!q1.empty()) { data u=q1.front(); q1.pop(); for (int i=0;i<8;i++) { data w; w.x=u.x+dx[i];w.y=u.y+dy[i]; if (w.x<1||w.x>n||w.y<1||w.y>m) continue; if (vis1[w.x][w.y]||map[w.x][w.y]==2) continue; if (map[w.x][w.y]>2||map[w.x][w.y]==0) addedge(z,num[w.x][w.y]); else q1.push(w); vis1[w.x][w.y]=1; } } } void spfa() { memset(f,inf,sizeof(f)); f[s]=0; g[s]=1; vis2[s]=1; q2.push(s); while (!q2.empty()) { int u=q2.front(); q2.pop(); for (int i=last[u];i;i=e[i].next) if (f[u]+1<f[e[i].to]) { f[e[i].to]=f[u]+1; g[e[i].to]=g[u]; if (!vis2[e[i].to]) { vis2[e[i].to]=1; q2.push(e[i].to); } } else if (f[u]+1==f[e[i].to]) g[e[i].to]+=g[u]; vis2[u]=0; } } int main() { scanf("%d%d",&n,&m); for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) { scanf("%d",&map[i][j]); if (map[i][j]==3) { num[i][j]=++tot; s=tot; } if (map[i][j]==4) { num[i][j]=++tot; t=tot; } if (map[i][j]==0) num[i][j]=++tot; } for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) if (num[i][j]) bfs(i,j,num[i][j]); spfa(); if (f[t]==inf) { printf("-1"); return 0; } printf("%d\n%lld",f[t]-1,g[t]); return 0; }
相关文章推荐
- BZOJ 1698 [Usaco2007 Feb]Lilypad Pond 荷叶池塘 BFS+最短路
- bzoj 1698: [Usaco2007 Feb]Lilypad Pond 荷叶池塘(BFS)
- bzoj1698 [Usaco2007 Feb]Lilypad Pond 荷叶池塘 [BFS]
- 【bzoj1698】[Usaco2007 Feb]Lilypad Pond 荷叶池塘
- BZOJ1698: [Usaco2007 Feb]Lilypad Pond 荷叶池塘
- BZOJ 1698 (USACO 2007 Feb)Liypad Pond (黄金)荷叶池塘
- POJ3271/BZOJ 1698: [Usaco2007 Feb]Lilypad Pond 荷叶池塘
- bzoj 1632: [Usaco2007 Feb]Lilypad Pond【bfs】
- bzoj 1632: [Usaco2007 Feb]Lilypad Pond(BFS)
- bzoj 1632: [Usaco2007 Feb]Lilypad Pond SPFA
- [BZOJ1632][Usaco2007 Feb]Lilypad Pond(spfa)
- [BZOJ1632][Usaco2007 Feb]Lilypad Pond(spfa)
- bzoj 1632: [Usaco2007 Feb]Lilypad Pond (spfa)
- bzoj 1632: [Usaco2007 Feb]Lilypad Pond bfs
- 【BZOJ】1632: [Usaco2007 Feb]Lilypad Pond(bfs)
- bzoj1632 [Usaco2007 Feb]Lilypad Pond
- bzoj1632 [Usaco2007 Feb]Lilypad Pond
- BFS妙题1632: [Usaco2007 Feb]Lilypad Pond
- 【C++心路历程35】【bzoj1632】[Usaco2007 Feb]Lilypad Pond
- bzoj:1632: [Usaco2007 Feb]Lilypad Pond