bzoj3432
来源:互联网 发布:网络刷手一天能挣多少 编辑:程序博客网 时间:2024/05/21 22:25
分析:一眼题,直接二分,然后用bfs判断,然而sb的我一开始以为要把每两个点之间都跑一遍。。结果走到宿舍的路上突然发现会超时。。然后想了想根本不用任意两个点之间遍历一遍,直接全图扫一遍,看看1的数量是不是等于原图就行了。。
#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>#define fo(i,a,b) for(int i=a;i<=b;i++)using namespace std;const int N=505;typedef long long ll;int bz[N][N],map[N][N],map1[N][N];int sum=0;struct node{ int x,y;}e[N*N],q[N*N];int n,m,tot;const int dx[4]={0,1,0,-1};const int dy[4]={1,0,-1,0};bool bfs(int d){ int sx=1,sy=1,ex=n,ey=m; int t=0,w=1; int cnt=0; memset(bz,0,sizeof(bz)); bz[sx][sy]=1; if (map1[sx][sy]==1)cnt++; q[1].x=sx,q[1].y=sy; while (t<w) { int x=q[++t].x; int y=q[t].y; fo(k,0,3) { int x1=x+dx[k]; int y1=y+dy[k]; if (x1>=1&&x1<=n&&y1>=1&&y1<=m&&abs(map[x][y]-map[x1][y1])<=d&&!bz[x1][y1]) { q[++w].x=x1; q[w].y=y1; bz[x1][y1]=1; if (map1[x1][y1]==1)cnt++; } } } if (sum==cnt)return 1; return 0;}int main(){ //int tot=0; scanf("%d%d",&n,&m); fo(i,1,n) fo(j,1,m) { scanf("%d",&map[i][j]); } fo(i,1,n) fo(j,1,m) { int x; scanf("%d",&x); map1[i][j]=x; if (map1[i][j]==1)sum++; } int l=0,r=1000000000,ans=0; while(l<=r) { int mid=(l+r)>>1; if(bfs(mid)) { ans=mid; r=mid-1; } else l=mid+1; } printf("%d\n",ans);}
0 0