题意:
要从起点走到终点,但是路径要离敌军尽可能的远。输出路径中离敌军最近的距离和路径长度。
思路:
先用BFS预处理限定区域内每个点到每一个敌军军营的距离,同时得到一个最大的距离范围maxdis。
然后在0-maxdis之间二分枚举,bfs找能从起点到终点且尽可能远的路径。
总结:
1、queue<node> q 如果做为全局变量每次用都要注意清空。
2、不需要ans找最小值,直接就是枚举能离的最远距离的最小值,用bfs跑出的距离cost就是路径长度。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
struct node
{
int x,y,step;
}enemy;
int sx,sy,ex,ey,ans,cost,maxdis;
int map[1010][1010];
bool vis[1010][1010];
queue<node> q;
int dx[]={-1,1,0,0};
int dy[]={0,0,-1,1};
int n,X,Y;
bool ok(int x,int y)
{
if(x>=0 && x<X && y<Y && y>=0)
return true;
return false;
}
void presolve()
{
while(!q.empty())
q.pop();
//queue<node> q;
for(int i=0;i<n;i++)
{
scanf("%d%d",&enemy.x,&enemy.y);
enemy.step=0;
map[enemy.x][enemy.y]=0;
q.push(enemy);
}
node cur,next;
while(!q.empty())
{
cur=q.front();
q.pop();
for(int i=0;i<4;i++)
{
next.x=cur.x+dx[i];
next.y=cur.y+dy[i];
next.step=cur.step+1;
if(ok(next.x,next.y) && map[next.x][next.y]==-1)
{
map[next.x][next.y]=next.step;
maxdis=max(maxdis,next.step);
q.push(next);
}
}
}
}
bool bfs(int dis)
{
while(!q.empty())
q.pop();
//queue<node> q;
node a,b,c;
a.x=sx,a.y=sy,a.step=0;
q.push(a);
while(!q.empty())
{
b=q.front();
if(b.x==ex && b.y==ey)
{
cost=b.step;
return true;
}
q.pop();
for(int i=0;i<4;i++)
{
c.x=b.x+dx[i];
c.y=b.y+dy[i];
c.step=b.step+1;
if(ok(c.x,c.y) && !vis[c.x][c.y] && map[c.x][c.y]>=dis)
{
vis[c.x][c.y]=true;
q.push(c);
}
}
}
return false;
}
int main()
{
int T;
scanf("%d",&T);
for(int i=0;i<T;i++)
{
scanf("%d%d%d",&n,&X,&Y);
memset(map,-1,sizeof(map));
maxdis=-1,ans=-1;
scanf("%d%d%d%d",&sx,&sy,&ex,&ey);
presolve();
/*for(int i=0;i<X;i++)
{
for(int j=0;j<Y;j++)
{
printf("%d ",map[i][j]);
}
printf("\n");
}*/
int bot=0,top=maxdis+10,mid;
while(bot<top)
{
mid = (bot+top)>>1;
if(map[sx][sy]<mid)
{
top=mid;
continue;
}
memset(vis,0,sizeof(vis));
if(bfs(mid))
{
bot=mid+1;
//ans=max(ans,cost);
}
else top=mid;
}
printf("%d %d\n",bot-1,cost);
}
return 0;
}