洛谷P1514 引水入城

想用搜索水一水,结果一水就是一下午emmm

用第一层的点去更新其他层的点,并记录能更新到的最远的端点,然后下面判断是否最底层都能到达,都能到达就通过记录的左右端点来更新,使在最少使用的情况下框到最大的范围就行了

代码

//By AcerMo
#include<cmath>
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int M=555;
int fx[5][2]={{1,0},{0,1},{0,-1},{-1,0}};
int n,m,ans=0;
int high[M][M];
bool vis[M][M];
int l[M][M],r[M][M];
int read()
{
	int x=0;char ch=getchar();
	while (ch>'9'||ch<'0') ch=getchar();
	while (ch>='0'&ch<='9') x=x*10+ch-'0',ch=getchar();
	return x;
}
inline void dfs(int x,int y)
{
	vis[x][y]=1;
	for (int i=0;i<4;i++)
	{
		int xx=x+fx[i][0];
		int yy=y+fx[i][1];
		if (xx<1||yy<1||xx>n||yy>m) continue;
		if (high[xx][yy]>=high[x][y]) continue;
		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]);	
	}
	return ;	
} 
int main()
{
	n=read();m=read();
	for (int i=1;i<=n;i++)
	for (int k=1;k<=m;k++)
	high[i][k]=read();
	memset(l,0x3f,sizeof(l));
	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]) cnt++,flag=1;
	if (flag){puts("0");printf("%d",cnt);return 0;}
	int le=1;
	while (le<=m)
	{
		int maxa=0;
		for (int i=1;i<=m;i++)
			if (l[1][i]<=le) maxa=max(maxa,r[1][i]);
		cnt++;le=maxa+1;
	}
	puts("1");
	printf("%d",cnt);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/acerandaker/article/details/80914808