bfs 大逃亡

来源:互联网 发布:道亨软件多少钱 编辑:程序博客网 时间:2024/06/02 19:42

问题 C: 大逃亡
时间限制: 1 Sec 内存限制: 256 MB
题目描述
给出数字N(1<=N<=10000),X(1<=x<=1000),Y(1<=Y<=1000),代表有N个敌人分布一个X行Y列的矩阵上,矩形的行号从0到X-1,列号从0到Y-1再给出四个数字x1,y1,x2,y2,代表你要从点(x1,y1)移到(x2,y2)。在移动的过程中你当然希望离敌人的距离的最小值最大化,现在请求出这个值最大可以为多少,以及在这个前提下,你最少要走多少步才可以回到目标点。注意这里距离的定义为两点的曼哈顿距离,即某两个点的坐标分为(a,b),(c,d),那么它们的距离为|a-c|+|b-d|。
输入
第一行给出数字N,X,Y
第二行给出x1,y1,x2,y2
下面将有N行,给出N个敌人所在的坐标。
输出
在一行内输出你离敌人的距离及在这个距离的限制下,你回到目标点最少要移动多少步。
样例输入
2 5 6
0 0 4 0
2 1
2 3
样例输出
2 14

明显是广搜,首先处理出每个点到敌人最小距离,然后因为答案一定是满足单调性的,如果某一个距离满足,那比他小的一定不是最优,因此就可以二分了满足条件就是终点能被更新)
我考试时打了两遍spfa,一遍处理出了到终点的最大距离。。然后果断T了两个点。。

#include<cstdio>#include<cstdlib>#include<cstring>#include<iostream>#include<algorithm>#include<queue>#define N 1005using namespace std;int read(){    int sum=0,f=1;char x=getchar();    while(x<'0'||x>'9'){if(x=='-')f=-1;x=getchar();}    while(x>='0'&&x<='9'){sum=(sum<<1)+(sum<<3)+x-'0';x=getchar();}    return sum*f;}struct zb{int x,y;}S,T;int n,ans,s,X,Y,dis[N][N],vis[N][N],d[N][N];int wz[5][2]={0,-1,-1,0,0,1,1,0};queue<zb> q;inline void bfs(){    while(!q.empty())    {        zb x=q.front();        for(int i=0;i<4;i++)        {            zb k;k.x=x.x+wz[i][0],k.y=x.y+wz[i][1];            if(k.x<0||k.x>=X||k.y<0||k.y>=Y)continue;            if(dis[k.x][k.y]>dis[x.x][x.y]+1)            {                dis[k.x][k.y]=dis[x.x][x.y]+1;                if(!vis[k.x][k.y])                {                    vis[k.x][k.y]=1;                    q.push(k);                }            }        }        vis[x.x][x.y]=0;q.pop();    }}inline bool spfa2(int m){    if(dis[S.x][S.y]<m||dis[T.x][T.y]<m)return 0;    vis[S.x][S.y]=1;d[S.x][S.y]=0;    q.push(S);    while(!q.empty())    {        zb x=q.front();        for(int i=0;i<4;i++)        {            zb k;k.x=x.x+wz[i][0],k.y=x.y+wz[i][1];            if(k.x<0||k.x>=X||k.y<0||k.y>=Y||dis[k.x][k.y]<m)continue;            if(d[k.x][k.y]>d[x.x][x.y]+1)            {                d[k.x][k.y]=d[x.x][x.y]+1;                if(!vis[k.x][k.y])                {                    vis[k.x][k.y]=1;                    q.push(k);                }            }        }        q.pop();vis[x.x][x.y]=0;    }    if(d[T.x][T.y]<100000){s=m;ans=d[T.x][T.y];return 1;}    return 0;}int main(){    n=read();X=read();Y=read();    S.x=read();S.y=read();    T.x=read();T.y=read();    memset(dis,60,sizeof(dis));    for(int i=1;i<=n;i++)    {        zb x;x.x=read();x.y=read();        vis[x.x][x.y]=1;dis[x.x][x.y]=0;q.push(x);    }    bfs();    int l=0,r=X+Y,mid;    while(l<=r)    {        memset(d,60,sizeof(d));        mid=(l+r)/2;        if(spfa2(mid))l=mid+1;        else r=mid-1;    }    printf("%d %d\n",s,ans);}