搜索水题
但是我还是wa了好几次,把求不能收到水的看成能收到水的了。。。。
大概解法就是先bfs出来所有靠湖的城能波及到的靠沙漠的,然后判断一下行不行,行的话就dp
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int dx[]={0,1,0,-1},dy[]={1,0,-1,0};
int n,m,g[505][505],used[505],now,f[505][505];
bool vis[505][506];
struct RES{int l,r;}res[505];
bool cmp(RES x,RES y) {return x.l<y.l;}
struct Node{int x,y;};queue<Node>q;
inline void bfs(const int x) {
res[now].l=100000;
q.push((Node){1,x});vis[1][x]=1;
while(!q.empty()) {
const int x=q.front().x,y=q.front().y;q.pop();
if(x==n) res[now].l=min(res[now].l,y),res[now].r=max(res[now].r,y),used[y]=1;
for(int d=0;d<4;d++) {
const int nx=x+dx[d],ny=y+dy[d];
if(nx>0&&nx<=n&&ny>0&&ny<=m&&g[nx][ny]<g[x][y]&&vis[nx][ny]==false) vis[nx][ny]=true,q.push((Node){nx,ny});
}
}
}
int main() {
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d",&g[i][j]);
for(int i=1;i<=m;i++) if(g[1][i-1]<=g[1][i]&&g[1][i+1]<=g[1][i]) memset(vis,0,sizeof vis),++now,bfs(i);
sort(res+1,res+1+now,cmp);int cnt=0;
bool flag=0;
for(int i=1;i<=m;i++) {if(used[i])cnt++;else flag=1;}
if(flag) {printf("0
%d",m-cnt);return 0;}
printf("1
");
memset(f,0x3f,sizeof f);
f[0][0]=0;
for(int i=1;i<=now;i++) {
f[i][0]=0;
for(int j=1;j<=m;j++) {
f[i][j]=min(f[i-1][j],f[i][j]);
if(res[i].l<=j) f[i][res[i].r]=min(f[i][res[i].r],f[i][j-1]+1);
}
}
printf("%d
",f[now][m]);
}