[HDU] 2612 Find a way 用单源最短论经模拟的简单广搜

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=2612

方法:其实就是从两个点分别探寻单源最短路径,两个点到同一个目标位置的最短路径都求出来,相加,然后找出到哪一个相同目标位置的最短路径之和最小即可,采用的模拟dijsktral算法。

要注意的一个地方是,找到一个kfc后一定还要继续去找,而不是向其他广搜题那样就停止探寻了,不能有思维定势啊。

实现方法为,初始的时候将两个源点到目标位置的距离设置为正无穷,然后分别用单元最短路径的算法模拟广搜并更新到目标位置的距离,最后在目标位置中找到最短路径之和最小的,由于正无穷和任何数之和都是正无穷,所以如果遇到不是被两个源点都可以达目标位置时,起路径和为正无穷,在比较的时候都会被忽略掉。

除此之外,记录目标位置坐标的数组不能开在200内,这里要细心,这里最多可以用接近4万个。

感想:思维定势造成一个下面如此简单的测试数据拜掉,wa了很久。

       3 5
                    Y...@
                    ####@
                    M....

代码:

View Code
#include <iostream>
#include <queue>
#include<algorithm>
using namespace std;
int n,m;
char map[202][202];
int dY[202][202];
int dM[202][202];
const char wall='#';
const char road='.';
const char Y='Y';
const char M='M';
const char KFC='@';
const int MAX=0x7fffffff;
int YposX,YposY,MposX,MposY;
bool v[202][202];
int deriction[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
struct Step
{
    int x,y;
    int currentUsedTime;
};
void BFSSearch(char who)
{ 
    memset(v,false,sizeof(v));
    int x = who == Y ? YposX:MposX;
    int y = who == Y ? YposY:MposY;
    Step step;
    step.x = x;
    step.y = y;
    step.currentUsedTime = 0;
    queue<Step> q;
    q.push(step);
    while(!q.empty())
    {
        Step t_step = q.front();
        q.pop();
        if(!v[t_step.x][t_step.y])
        {
            v[t_step.x][t_step.y]= true;
            if(map[t_step.x][t_step.y]==KFC)
            {
                if(who == Y && dY[t_step.x][t_step.y]>t_step.currentUsedTime)
                    dY[t_step.x][t_step.y]=t_step.currentUsedTime;
                if(who == M && dM[t_step.x][t_step.y]>t_step.currentUsedTime)
                    dM[t_step.x][t_step.y]=t_step.currentUsedTime;
            }
            //下面的部分不能放在与上面对应的else里面,找一个kfc还要继续找,
            //这样才符合dijsktral算法的特点。
            //不要受一般广搜的思维定势限制。
            //否则下面测试数据肯定要败掉
            /*
                    3 5
                    Y...@
                    ####@
                    M....
            */
            int n_x,n_y;
            Step n_step;
            for(int i =0;i<4;i++)
            {
                n_x = t_step.x+deriction[i][0];
                n_y = t_step.y+deriction[i][1];
                if(map[n_x][n_y]!=wall && !v[n_x][n_y])
                {
                    n_step.x=n_x;
                    n_step.y=n_y;
                    n_step.currentUsedTime = t_step.currentUsedTime+1;
                    q.push(n_step);
                }
            }
           
        }
    }
}
 
int MyAdd(int x,int y)
{
    if(x==MAX ||y ==MAX)
        return MAX;
    return x+y;
}
int MyCmp(int x,int y)
{
    return x<y ? x : y;
}
 
void main()
{
    while(scanf("%d %d",&n,&m)!=EOF)
    {
        memset(map,wall,sizeof(map));
        memset(dY,0,sizeof(dY));
        memset(dM,0,sizeof(dM));
        int recordKFC[40000][2];
        int k=0;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
            {
                cin>>map[i][j];
                if(map[i][j] == Y)
                {
                    YposX = i;
                    YposY=j;
                }
                if(map[i][j] == M)
                {
                    MposX = i;
                    MposY=j;
                }
                if(map[i][j] == KFC)
                {
                    dY[i][j] = dM[i][j] = MAX;
                    recordKFC[k][0] = i;
                    recordKFC[k][1] = j;
                    k++;
                }
            }
        BFSSearch(Y);
        BFSSearch(M);
        int re = MAX;
        for(int x=0;x<k;x++)
            re = MyCmp(re, MyAdd(dY[ recordKFC[x][0] ] [ recordKFC[x][1] ],dM[ recordKFC[x][0] ] [ recordKFC[x][1] ]    ));
        cout<<11*re<<endl;
    }
}
原文地址:https://www.cnblogs.com/kbyd/p/3032273.html