hdu2337Escape from Enemy Territory(预处理+二分+bfs)
来源:互联网 发布:java ssh项目源码下载 编辑:程序博客网 时间:2024/05/16 08:04
题目请戳这里
题目大意:一个二维平面上有n个敌人据点,给一个起点和一个终点,求这个起点到终点的所有路径中距离敌人据点最近距离最大的前提下总长度最短.求这条路径距离敌人据点最近距离和这条路径的最小长度.
题目分析:数据范围:n不大于10000,二维平面不大于1000*1000.所有点不重复,且均在平面上.
首先直观的感受是二分距离再bfs.不过数据范围有点大,特别是在判断某个点合法的时候要迅速判断这个点与n个敌人据点的最近距离.直接上会TLE.
我的做法是先预处理一下.首先路径距离敌人所有据点最短距离是知道的,输入的时候可以搞出来.设这个值为maxans.然后初始化地图,所有点一开始假设合法,初始化无穷大.然后从输入的n个敌人据点开始bfs,半径为maxans.
然后再上二分距离+bfs.这样可以O(1)的时间判断某个点是否合法.
我的代码跑的好慢的样子......
详情请见代码:
#include <iostream>#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>using namespace std;const int N = 1001;const int M = 1000004;const int NM = 10001;struct node{ int x,y,step;}que[M],ss,now;int n,m,nm,sx,sy,ex,ey,maxans,minans,minlen;int pt[NM][2];bool flag[N][N];int dist[N][N];int dir[4][2] = {{-1,0},{0,-1},{0,1},{1,0}};int dis(int a,int b,int c,int d){ return (abs(a - c) + abs(b - d));}void Bfs(int id){ ss.x = pt[id][0]; ss.y = pt[id][1]; ss.step = 0; int i,head,tail; head = tail = 0; que[tail ++] = ss; memset(flag,false,sizeof(flag)); flag[ss.x][ss.y] = true; while(head != tail) { now = que[head ++]; if(head == M) head = 0; if(now.step > maxans) return; dist[now.x][now.y] = min(dist[now.x][now.y],now.step); ss = now; ss.step ++; for(i = 0;i < 4;i ++) { ss.x = now.x + dir[i][0]; ss.y = now.y + dir[i][1]; if(ss.x >= 0 && ss.y >= 0 && ss.x < n && ss.y < m && !flag[ss.x][ss.y]) { flag[ss.x][ss.y] = true; que[tail ++] = ss; if(tail == M) tail = 0; } } }}void init(){ scanf("%d%d%d",&nm,&n,&m); scanf("%d%d%d%d",&sx,&sy,&ex,&ey); maxans = 0x3f3f3f3f; memset(dist,0x3f,sizeof(dist)); for(int i = 0;i < nm;i ++) scanf("%d%d",&pt[i][0],&pt[i][1]),maxans = min(maxans,dis(sx,sy,pt[i][0],pt[i][1])); for(int i = 0;i < nm;i ++) Bfs(i);}bool isok(int x,int y,int cmp){ if(x < 0 || y < 0 || x >= n || y >= m) return false; else { return dist[x][y] >= cmp;// for(int i = 0;i < nm;i ++)// if(dis(x,y,pt[i][0],pt[i][1]) < cmp)// return false; }}bool bfs(int lim){ ss.x = sx; ss.y = sy; ss.step = 0; memset(flag,false,sizeof(flag)); flag[sx][sy] = true; int head,tail,i; head = tail = 0; que[tail ++] = ss; while(head != tail) { now = que[head ++]; if(head == M) head = 0; ss = now; ss.step ++; for(i = 0;i < 4;i ++) { ss.x = now.x + dir[i][0]; ss.y = now.y + dir[i][1]; if(isok(ss.x,ss.y,lim) && !flag[ss.x][ss.y]) { if(ss.x == ex && ss.y == ey) { minlen = ss.step; return true; } flag[ss.x][ss.y] = true; que[tail ++] = ss; if(tail == M) tail = 0; } } } return false;}void fuck(){ init(); int l,r,mid; l = 0;r = maxans; minans = maxans;minlen = dis(ex,ey,sx,sy); while(l <= r) { mid = (l + r)>>1; if(bfs(mid)) { minans = mid; l = mid + 1; } else r = mid - 1; } printf("%d %d\n",minans,minlen);}int main(){ int t; scanf("%d",&t); while(t --) { fuck(); } return 0;}//3187MS15560K
0 0
- hdu2337Escape from Enemy Territory(预处理+二分+bfs)
- POJ 3601 Escape from Enemy Territory (二分+BFS+预处理)
- hdu 2337 Escape from Enemy Territory (二分枚举+预处理+bfs)
- hdu2337 Escape From Enemy Territory---二分bfs+预处理
- poj 3501 Escape from Enemy Territory(预处理&二分&bfs)
- poj3501Escape from Enemy Territory||hdu2337Escape from Enemy Territory
- Escape from Enemy Territory(二分+bfs)
- hdu 2337 Escape from Enemy Territory (presolve bfs +bfs+二分)
- hdu 2337 Escape from Enemy Territory (预处理+二分+搜索)
- hdu 2337 Escape from Enemy Territory (预处理+二分+宽搜)
- poj 3501 Escape from Enemy Territory 二分+bfs
- HDU 2337 Escape from Enemy Territory(BFS+二分优化)
- POJ 3501 - Escape from Enemy Territory
- hdu 2337 Escape from Enemy Territory
- 3094Escape from Enemy Territory——zoj
- Learning from the enemy
- HDU 3681 Prison Break (二分答案+状压DP+bfs预处理)
- enemy
- AWS中国(北京)区域发布的常见问题回答
- cycle结构体的四级指针详解
- java学习笔记04-2
- Numpy 基础数据类型 (一)
- 一篇厚道的Autolayout及VFL经验分享
- hdu2337Escape from Enemy Territory(预处理+二分+bfs)
- Spiral Matrix II
- Hadoop之MapReduce WordCount分析
- uva 524 - Prime Ring Problem(dfs)
- openwrt wiki 为按键添加功能--简单方便
- php写一个简单的登录程序
- java疑问
- Ants(POJ No.1852) 脑筋急转弯
- python configure