[洛谷P1514][题解]引水入城

首先明确一个事情:如果能全部覆盖,那么一个蓄水厂覆盖到的区间一定是连续的
所以
先染色判断能否覆盖到,然后贪心覆盖一下就好了
代码:

#define N 510
int n,m;
int mp[N][N],l[N][N],r[N][N],vis[N][N];
int dx[4]={1,0,-1,0},dy[4]={0,1,0,-1};
void DFS(int x,int y){//求每个蓄水厂能覆盖到的区间
	vis[x][y]=1;
	for(rg int i=0;i<4;i++){
		int xx=x+dx[i],yy=y+dy[i];
		if(xx<1||xx>n||yy<1||yy>m)continue;
		if(mp[xx][yy]<mp[x][y]){
			if(!vis[xx][yy])DFS(xx,yy);
			l[x][y]=min(l[x][y],l[xx][yy]);
			r[x][y]=max(r[x][y],r[xx][yy]);
		}
	}
}
int main(){
	Read(n),Read(m);
	memset(l,0x3f,sizeof(l));
	for(rg int i=1;i<=n;i++){
		for(rg int j=1;j<=m;j++){
			Read(mp[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])DFS(1,i);
	}
	bool flag=0;
	int cnt=0;
	for(int i=1;i<=m;i++){//判断一下
		if(!vis[n][i]){
			flag=1;
			cnt++;
		}
	}
	if(flag){
		printf("0
%d
",cnt);
		return 0;
	}
	int L=1;
	while(L<=m){//贪心求
		int maxr=0;
		for(int i=1;i<=m;i++){
			if(l[1][i]<=L)maxr=max(maxr,r[1][i]);
		}
		cnt++;
		L=maxr+1;
	}
	printf("1
%d
",cnt);
	return 0;
}

原文地址:https://www.cnblogs.com/juruoajh/p/12774468.html