【刷题】【搜索】引水入城

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m;
const int N=503;
bool vis[N][N];//因为可能是死路,所以l,r不能表示这个点有没有更新过,所以要加vis标记 
int d[N][N];
int l[N][N],r[N][N];

int py[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
void dfs(int x,int y)
{
    vis[x][y]=true;
    for(int i=0;i<4;i++)
    {
        int nx=x+py[i][0];
        int ny=y+py[i][1];        
        if(!nx || !ny || nx>n || ny>m || d[nx][ny]>=d[x][y] ) continue;
        if(!vis[nx][ny])
            dfs(nx,ny);
        
        l[x][y]=min(l[x][y],l[nx][ny]);
        r[x][y]=max(r[x][y],r[nx][ny]);
    }
}

struct node
{
    int l,r;
    bool operator < (const node & o) const
    { return l<o.l; }
}xl[N];

int main()
{
    memset(l,0x3f,sizeof(l));
    
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            scanf("%d",&d[i][j]);
    for(int i=1;i<=m;i++)
        l[n][i]=r[n][i]=i;
    for(int i=1;i<=m;i++)
        if(!vis[1][i] && d[1][i]>=d[1][i+1] )//>=都不能被后面一个替代,因为等于的不查可能最后就不成功了 
            dfs(1,i);
    
    int fail=0;
    for(int i=1;i<=m;i++)
        if(!vis[n][i])
            fail++;
    if(fail)
    {
        printf("0
%d
",fail); 
        return 0;
    }
    else printf("1
"); 
    
    int nw=1,cnt=0;
    while(nw<=m)
    {
        int rr=nw-1;
        for(int i=1;i<=m;i++)
            if(l[1][i]<=nw && rr<r[1][i] )
                rr=r[1][i]; 
        cnt++; 
        nw=rr+1;
    }
    printf("%d
",cnt);
    return 0;
}
原文地址:https://www.cnblogs.com/xwww666666/p/11726082.html