二つのBFS(UVA 11624、2612 hdoj)

トピック:UVA 11624 火事だ!(ロス・バレーでは)
それは海外のOJであり、従ってアップ提出していないが、アイデアが習得されているため、魏、今日のタイトルのブラシkuangbinの首長では、二回BFSのタイトルを使用する必要があります最も重要。
影響を受ける:迷路の中に閉じ込めジョー、発火の迷路源、ジョー及び発火源は、1分間に1つのユニットを移動させることができ、火災のソースが1分(そうでない場合、次に壁)内で四方に広がることができ、ジョーは、あなたが逃げることができるならば、(たとえ成功した脱出の端に行ってきました)迷路を脱出するために見つける出力最短の時間、そうでない場合、出力「IMPOSSIBLE」でした。
(注:火のない唯一の情報源!!!)
ソリューション:ジョー・パスが火災の広がりを変更しないと、火災の広がりがジョーのパスを変更しますので、完了するまでに二回BFSを使用することを選択したため、この問題があります。BFSは火がBFSを書く時間内のすべての場所に広がっていくで、BFSは再びジョールートを検索します。一つの要素が無限大であるとき、配列の初期化時の開始時にこの場所は火に到達できないことを、無限です。マップの存在下では、発火の複数のソースがあるかもしれないとして、あなたは裁判官は「F」ではありません、そうであれば、チームに何を読みたいと思うたびにそう。この位置に到達する前に、ジョーのBFS、時間のチェックでは、位置が実現可能であることを示す、火災よりもジョーた場合、この位置に必要な時間に延焼の場所に到達するためにジョーを比較します。
コード上で(正しくない場合は必ず、友人が常にUVAコンパイルエラー、訓練を受け、訓練を受け、訓練を受けた、〜を言います)

#include <iostream>
#include <queue>
#include <string.h>
using namespace std;
char maps[1001][1001];
int vis[1001][1001];
int time[1001][1001];
int dir[4][2]=
{
    {1,0},
    {-1,0},
    {0,1},
    {0,-1},
};
int sx,sy,r,c;
struct node
{
    int x;
    int y;
    int time;
};
queue<node>q;
bool check_fire(int x,int y)
{
    if(x<0||y<0||x>=c||y>=r)
        return false;
    else
    if(maps[x][y]=='#'||vis[x][y])
        return false;
    return true;
}
bool check_Joe(int x,int y,int times)
{
    if(x<0||y<0||x>=r||y>=c)
        return false;
    else
    if(maps[x][y]=='#'||vis[x][y]||times>=time[x][y])
        return false;
    return true;
}
void bfs_fire()
{
    node next;
    while(!q.empty())
    {
        node tmp=q.front();
        q.pop();
        for(int i=0;i<4;i++)
        {
            next=tmp;
            next.x+=dir[i][0];
            next.y+=dir[i][1];
            if(check_fire(next.x,next.y))
            {
                next.time++;
                vis[next.x][next.y]=1;
                time[next.x][next.y]=next.time;
                q.push(next);
            }
        }
    }
}
int bfs_Joe()
{
    node start,next;
    start.x=sx;
    start.y=sy;
    start.time=0;
    q.push(start);
    vis[sx][sy]=1;
    while(!q.empty())
    {
        node tmp=q.front();
        q.pop();
        if(tmp.x==0||tmp.y==0||tmp.x==r-1||tmp.y==c-1)
            return tmp.time+1;
        for(int i=0;i<4;i++)
        {
            next=tmp;
            next.x+=dir[i][0];
            next.y+=dir[i][1];
            next.time++;
            if(check_Joe(next.x,next.y,next.time))
            {
                vis[next.x][next.y]=1;
                q.push(next);
            }
        }
    }
    return -1;
}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        while(!q.empty())
            q.pop();
        cin>>r>>c;
        memset(maps,0,sizeof(maps));
        memset(vis,0,sizeof(vis));
        for(int i=0;i<r;i++)
        {
            for(int j=0;j<c;j++)
            {
                cin>>maps[i][j];
                if(maps[i][j]=='F')
                {
                    node tmp;
                    tmp.x=i;
                    tmp.y=j;
                    tmp.time=0;
                    time[i][j]=0;
                    vis[i][j]=1;
                    q.push(tmp);
                }
                else
                    if(maps[i][j]=='J')
                {
                    sx=i;
                    sy=j;
                }
            }
        }
        for(int i=0;i<1001;i++)
        {
            for(int j=0;j<1001;j++)
                time[i][j]=1e9+7;
        }
        bfs_fire();
        memset(vis,0,sizeof(vis));
        int ans=bfs_Joe();
        if(ans==-1)
            cout<<"IMPOSSIBLE"<<endl;
        else
            cout<<ans<<endl;
    }
}

トピック:hdoj 2612 のFind Aウェイ
の質問は、自分のヨ〜ああ魏の外であることを
効果対象:ありKFC MとY満たすために行くには二人がありますが、市は、彼らは、ノートと最短時間を探しているKFC、KFCをたくさん持っている:使用している場合二人、二人が使用している場合ではないことを、最長の合計時間です。
ソリューション:、このタイトルを参照してください各BFSはKFCを検索するための私の最初の考えはあるが、問題の首長への解決策を見た後、彼らは非常に多くがあるかもしれませんどのように多くのKFC、知っているが、していないので、その方法は、タイムアウトと述べましたそれがタイムアウトします。KFCに到達するために使用される二人の男を見つけるたびに、それに少なくとも合計時間を見つけて、YとMにBFSとの二人を望んでいた私はそう。2人がまったく同じであるため、ここで私は二回BFSを書く避けるために、3次元配列で、BFSで、3次元配列を使用していました。
ACコード:

#include <iostream>
#include <queue>
#include <string.h>
using namespace std;
char maps[201][201];
int kfc[201][201];//记录两人到达某个KFC的总时间
int vis[2][201][201];//用三维数组避免写两次bfs
int n,m,yx,yy,mx,my;
int mins=1e9+7;//记录两人到达某KFC的最短时间
struct node
{
    int x;
    int y;
    int time;
};
int dir[4][2]=
{
    {1,0},
    {-1,0},
    {0,1},
    {0,-1},
};
bool check(int x,int y,int k)
{
    if(x<0||y<0||x>=n||y>=m)
        return false;
    else
        if(maps[x][y]=='#'||vis[k][x][y])
            return false;
    return true;
}
void bfs()
{
    queue<node>q;
    node start,next;
    for(int k=0;k<2;k++)
    {
        if(k==0)
        {
            start.x=yx;
            start.y=yy;
        }
        else
        {
            start.x=mx;
            start.y=my;
        }
        start.time=0;
        q.push(start);
        vis[k][start.x][start.y]=1;
        while(!q.empty())
        {
            node tmp=q.front();
            q.pop();
            for(int i=0;i<4;i++)
            {
                next=tmp;
                next.x+=dir[i][0];
                next.y+=dir[i][1];
                if(check(next.x,next.y,k))
                {
                    next.time++;
                    if(maps[next.x][next.y]=='@')
                    {
                        kfc[next.x][next.y]+=next.time;
                        if(kfc[next.x][next.y]<mins&&k==1)//在这里判断大小的话,只能是在第二个人之后,因此要加上k==1这个判别条件
                            mins=kfc[next.x][next.y];//在这里判断就不用再在下面排序找最小值了
                    }
                    vis[k][next.x][next.y]=1;
                    q.push(next);
                }
            }
        }
    }
}
int main()
{
    while(cin>>n>>m)
    {
        mins=1e9+7;
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                cin>>maps[i][j];
                if(maps[i][j]=='Y')
                {
                    yx=i;
                    yy=j;
                }
                else
                    if(maps[i][j]=='M')
                {
                    mx=i;
                    my=j;
                }
            }
        }
        memset(kfc,0,sizeof(kfc));
        memset(vis,0,sizeof(vis));
        bfs();
        cout<<mins*11<<endl;
    }
}
公開された32元の記事 ウォン称賛12 ビュー1393

おすすめ

転載: blog.csdn.net/qq_18873031/article/details/98756347