题目来自洛谷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; }