bfs 大逃亡

问题 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 1005
using 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
",s,ans);
}
原文地址:https://www.cnblogs.com/QTY2001/p/7632688.html