题解 P1514 【引水入城】

· · 题解

看到好多题解都是2遍搜索,我只想说

只需要一遍Bfs,你就可以A掉它!

思路如下:我们从最后一行跑Bfs,记录下来哪些点可以灌溉到这个点。如果没有点能灌溉到,记下个数,退出;否则对区间排序进行贪心。

注意:这里有个坑点: 如果只有一行的话,没有被更新的点实际上比两边都高,意思是只要在这些点上建造水站就可以灌溉所有点,所以要输出1!

代码如下:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define Inf 501
using namespace std;
const int dx[4]={0,1,-1,0},dy[4]={1,0,0,-1};
int n,m;
int h[501][501],l[501],r[501];
int que[250010][2];
bool vis[501][501],ok[501];
struct node{
    int l,r;
    void cl(){
        l=Inf;
    }
}q[501];
inline void re(int &n){
    n=0;
    char ch=getchar();
    while(ch>'9'||ch<'0') ch=getchar();
    while(ch>='0'&&ch<='9') n=n*10+ch-'0',ch=getchar();
}
inline bool cmp(node a,node b){
    if(a.l!=b.l) return a.l<b.l;
    if(a.l==b.l) return a.r<b.r; 
}
inline void bfs(int x,int y){//简单的Bfs过程 
    int head=0,tail=1,x1,y1;
    memset(vis,0,sizeof(vis));
    que[1][0]=x;que[1][1]=y;vis[x][y]=1;
    while(head<tail){
        head++;
        for(int i=0;i<4;i++){
            x1=que[head][0]+dx[i];
            y1=que[head][1]+dy[i];
            if(x1<1||y1<1||x1>n||y1>m||h[que[head][0]][que[head][1]]>=h[x1][y1]||vis[x1][y1]) continue;
            vis[x1][y1]=1;//这里注意是反着搜的,意思是我们要找比它大的 
            tail++;
            que[tail][0]=x1;
            que[tail][1]=y1;
            if(x1==1){
                q[y].l=min(y1,q[y].l);
                q[y].r=max(y1,q[y].r);
            }
        }
    }
}
int main()
{
    re(n);re(m);
    for(int i=1;i<=n;i++)
      for(int j=1;j<=m;j++)
        re(h[i][j]);
    int tot=0;
    for(int i=1;i<=m;i++){
        q[i].cl();//初始化 
        bfs(n,i);//搜索 
        if(q[i].l==Inf) tot++;//没有被更新,记录下来 
    }
    if(tot){//如果有的点不能被灌溉到 
        if(n!=1) printf("0\n%d",tot);//如同我们上面说的,如果不是1行,就是有的点灌溉不到 
        else printf("1\n%d",tot); //如果是1行,则该点比左右都高,在该点建设就行,输出1,即能满足 
        return 0;
    }
    sort(q+1,q+m+1,cmp);//区间排序 
    int las=0;//las记录上一个水站的位置 
    for(int i=1;i<=m;i++){
        if(las>=q[i].l&&las<=q[i].r){
            continue;//如果上一个水站在这个区间里,不用管 
        }
        tot++;//贪心的思想,把每一个水站都尽量往后放,这样能满足的就更多 
        las=q[i].r;
    }
    printf("1\n%d\n",tot);
    return 0;
}