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;
}

  

posted @ 2017-10-06 20:06  wqtnb_tql_qwq_%%%  阅读(130)  评论(0编辑  收藏  举报