多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > 綜合技術 > BZOJ 1514 _ [POI2006]ZAB-Frogs 單調隊列+二分BFS

BZOJ 1514 _ [POI2006]ZAB-Frogs 單調隊列+二分BFS

來源:程序員人生   發布時間:2016-04-13 08:45:58 閱讀次數:2742次

題意:
給定1個網格圖,其中有1些壞點,要求使出發點到終點的路徑上的所有點到離該點最近的壞點的最小距離距離最大,求這個最大值。
解析:
讀完題明顯分為兩部份:
第1部份:預處理所有點到他最近的壞點的距離。
第2部份:2分最大距離bfs判定。
第2部份不用說吧?
主要就是卡在第1部份。
我們斟酌依照每列來計算每一個點的dis距離(即到他最近的壞點的距離)
明顯可以發現,對該列來講,每行都可能有1個到該列最近的點,并且我們發現,如果某1行有兩個壞點的話,假定分別為A,B,并且A到該列的距離最近,那末B明顯不會對這1列的dis有任何影響。
所以我們明顯可以在求之前預處理1下每行的如果存在壞點的那個最近的壞點的坐標。
接下來,我們討論壞點k,l,設我們要更新的點是(x,y)
如果k優于l,那末我們無妨列1下式子。

(Xk?x)2+(Yk?y)2<=(Xl?x)2+(Yl?y)2


X2k?X2l+2?x?Xl?2?x?XkYk?Yl+Yk+Yl<=2y

所以我們只需要按處理出來的壞點順序保護1個X2k?X2l+2?x?Xl?2?x?XkYk?Yl+Yk+Yl遞增便可。
更新的時候每次在其中2分查找最后1個<=2y的。
復雜度O(n*m*logn)
代碼:


#include #include #include #include #include #include #define N 1100 using namespace std; int n,m; int num; int calc[N][N]; int xx[]={0,1,-1,0,0}; int yy[]={0,0,0,-1,1}; struct node { int x,y; node(){} node(int _x,int _y):x(_x),y(_y){} friend istream& operator >> (istream &_,node &a) {scanf("%d%d",&a.x,&a.y);calc[a.y][++calc[a.y][0]]=a.x;return _;} friend bool operator == (node a,node b) {return a.x==b.x&&a.y==b.y;} node operator - (const node &a) {return node(x-a.x,y-a.y);} int operator * (const node &a) {return x*a.x+y*a.y;} }pt[N*N],st,ed; int dis[N][N]; int f[N][N]; node q[N]; node newq[N]; void init() { for(int i=1;i<=m;i++) sort(calc[i]+1,calc[i]+calc[i][0]+1); } int get_dis(node a,node b) { return (a-b)*(a-b); } double q_calc(node a,node b,int tmpx) { return (double)(a.x*a.x-b.x*b.x+2*tmpx*b.x-2*tmpx*a.x)/(a.y-b.y)+a.y+b.y; } void get_min_dis() { memset(dis,0x3f,sizeof(dis)); for(int i=1;i<=num;i++) dis[pt[i].x][pt[i].y]=0; for(int i=1;i<=n;i++) { int l=1,r=0; for(int j=1;j<=m;j++) { int ll=1,rr=calc[j][0],ans=ll; while(ll<=rr) { int mid=(ll+rr)>>1; if(calc[j][mid]<=i)ans=mid,ll=mid+1; else rr=mid-1; } if(ans+1<=calc[j][0]&&abs(calc[j][ans+1]-i)<abs(calc[j][ans]-i)) ans++; if(ans<=calc[j][0]) { node tmp; tmp.x=calc[j][ans],tmp.y=j; q[++r]=tmp; } } if(r==1) { for(int j=1;j<=m;j++) dis[i][j]=get_dis(node(i,j),q[r]); continue; } int tmpr=r; l=1,r=0; for(int j=1;j<=tmpr;j++) { while(lq[j],newq[r],i)<=q_calc(newq[r],newq[r⑴],i))r--; if(l>=r||q_calc(q[j],newq[r],i)>q_calc(newq[r],newq[r⑴],i)) newq[++r]=q[j]; } for(int j=1;j<=m;j++) { int ll=l+1,rr=r,ans=1; while(ll<=rr) { int mid=(ll+rr)>>1; if(q_calc(newq[mid],newq[mid⑴],i)<=2*j)ans=mid,ll=mid+1; else rr=mid-1; } dis[i][j]=min(get_dis(node(i,j),newq[ans]),dis[i][j]); } } } bool check(int x) { memset(f,0,sizeof(f)); queueque; if(dis[st.x][st.y]>=x) que.push(st),f[st.x][st.y]=1; while(!que.empty()) { node u=que.front(); que.pop(); for(int i=1;i<=4;i++) { node tmp; tmp.x=u.x+xx[i],tmp.y=u.y+yy[i]; if(tmp.x<=0||tmp.x>n||tmp.y<=0||tmp.y>m)continue; if(dis[tmp.x][tmp.y]>=x&&!f[tmp.x][tmp.y]) { f[tmp.x][tmp.y]=1; que.push(tmp); } } } return f[ed.x][ed.y]; } int main() { #ifndef ONLINE_JUDGE freopen("zab5ocen.in","r",stdin); freopen("1514.out","w",stdout); #endif scanf("%d%d",&n,&m); scanf("%d%d%d%d",&st.x,&st.y,&ed.x,&ed.y); scanf("%d",&num); for(int i=1;i<=num;i++)cin>>pt[i]; init(); get_min_dis(); int l=0,r=n*n+m*m,ans; while(l<=r) { int mid=(l+r)>>1; if(check(mid))l=mid+1,ans=mid; else r=mid-1; } printf("%d ",ans); #ifndef ONLINE_JUDGE fclose(stdin);fclose(stdout); #endif return 0; }
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 久久99国产精品久久99 | 日韩一级片免费看 | 最近免费中文字幕大全高清大全1 | 国产免费a v吧在线观看不卡 | 操操操网站 | 日本做人爱免费视频 | 性色免费视频 | 看黄色免费网站 | 日产高清卡一卡二无卡三区 | 免费播放欧美毛片欧美a | a级网站在线观看 | 成 人 亚洲 综合天堂 | 性吧影院 | 国产亚洲精品久久久久91网站 | 在线视频 一区二区 | 校园春色 亚洲色图 | 狂野欧美性猛交xxxx乱大交 | 欧美日韩国产欧美 | 亚洲码在线观看 | 欧美极品videosvideoxxx | 爱爱小视频在线看免费 | 免费观看一级欧美在线视频 | 中日韩欧美中文字幕毛片 | 九色网址 | 操片| 日韩一级片在线免费观看 | 亚洲乱码一二三四区国产 | 午夜网站免费 | 欧美曰韩一区二区三区 | 中文字幕中文字幕中中文 | 日本 欧美 在线 | 欧美日韩国产超高清免费看片 | free性欧美hd另类精品 | 欧美在线aa | japanese17一18sex日本护士 | 午夜影院免费在线观看 | 欧美高清视频手机在在线 | 国产一级第一级毛片 | 亚洲日本视频 | 91久久人澡人人添人人爽 | 成人淫片 |