luogu_1514 引水入城
#include <cstdio> #include <iostream> using namespace std; const int N=510; const int INF=1<<30; struct Node{int l,r;}p[N][N]; int n,m,h[N][N],dp[N]; int dx[]={-1,0,1,0}; int dy[]={0,1,0,-1}; bool vis[N][N]; bool cmp(Node a,Node b){ if(a.r==b.r)return a.l<b.l; return a.r<b.r; } inline void dfs(int x,int y){ vis[x][y]=1; for(register int i=0;i<4;i++){ int x1=x+dx[i],y1=y+dy[i]; if(x1>0 && x1<=n && y1>0 && y1<=m && h[x1][y1]<h[x][y]){ if(!vis[x1][y1])dfs(x1,y1); p[x][y].l=min(p[x][y].l,p[x1][y1].l); p[x][y].r=max(p[x][y].r,p[x1][y1].r); } } } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){ scanf("%d",&h[i][j]); p[i][j].l=INF; } for(register int i=1;i<=m;i++)p[n][i].l=p[n][i].r=i; for(register int i=1;i<=m;i++)dfs(1,i); int num=0; for(register int i=1;i<=m;i++) if(!vis[n][i])num++; if(num){cout<<0<<endl<<num<<endl; return 0;} for(register int i=1;i<=m;i++)dp[i]=INF; for(register int i=1;i<=m;i++) if(p[1][i].l<=p[1][i].r){ dp[p[1][i].r]=min(dp[p[1][i].r],dp[p[1][i].l-1]+1); for(register int j=p[1][i].r-1;j;j--)dp[j]=min(dp[j],dp[j+1]); } printf("1\n%d\n",dp[m]); return 0; }