搜索 引水入城 1514

题目链接

题目来自洛谷1514 引水入城

很清新的一道搜索题,先造出每个蓄水厂的可浇灌区间,因为如果区间不连贯,必定会出现交叉相灌的情况,交叉意味着两条路都能走,假设不成立。

再贪心求得最小覆盖值,值得一说的是贪心用的方法是跳过大区间内包含的小区间,直到下一个与上一个r值不相交l值出现时答案才加一。

其他没什么好说的了。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
int ans=99999999,maxn=99999999;
int m,n,cnt,fl,now;
int be[502],a[502][502],v[502][502];
struct llo{
    int l,r;
} e[503],d[503];
int cmp(llo x,llo y){
    if(x.l==y.l)    return x.r>y.r;    
    return x.l<y.l;
}
void fugai(int num,int nx,int ny){
    v[nx][ny]=1;
    if(nx==n){
        be[ny]=1;
        e[num].l=min(e[num].l,ny);
        e[num].r=max(e[num].r,ny);
    }
    if(nx!=1&&a[nx][ny]>a[nx-1][ny]&&v[nx-1][ny]==0){
        fugai(num,nx-1,ny);
    }
    if(nx!=n&&a[nx][ny]>a[nx+1][ny]&&v[nx+1][ny]==0){
        fugai(num,nx+1,ny);
    }
    if(ny!=1&&a[nx][ny]>a[nx][ny-1]&&v[nx][ny-1]==0){
        fugai(num,nx,ny-1);
    }
    if(ny!=m&&a[nx][ny]>a[nx][ny+1]&&v[nx][ny+1]==0){
        fugai(num,nx,ny+1);
    }
}

int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            scanf("%d",&a[i][j]);
        }    
    }
    for(int i=1;i<=m;i++)    e[i].l=99999999;
    for(int i=1;i<=m;i++){
        memset(v,0,sizeof(v));
        if(a[1][i]>=a[1][i-1]&&a[1][i]>=a[1][i+1]){
            fugai(i,1,i);
        }
    }
    for(int i=1;i<=m;i++){
        if(be[i]==0)    fl++; 
    }
    if(fl!=0){
        printf("0
%d",fl);
        return 0;
    }
    now=1;cnt=0;
    for(int i=1;i<=m;i++){
        if(e[i].l==99999999)    continue;
        cnt++;
        d[cnt].l=e[i].l;
        d[cnt].r=e[i].r;
    }
    now=1;int ccc=1;ans=0;
    sort(d+1,d+cnt+1,cmp);
    while(ccc<=m){
        int numm=0;
        while(d[now].l<=ccc){
            printf("%d %d %d
",d[now].l,ccc,d[now].r);
            numm=max(numm,d[now].r);
            now++;
        }
        ccc=numm+1;
        ans++;
    }
    printf("1
%d",ans);
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/jindui/p/11694658.html