zoukankan      html  css  js  c++  java
  • [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;
        }
    }
  • 相关阅读:
    AJAX下载,安装及使用(转)
    Vss命令行获取文件
    提升MOSS中运行权限
    数据库还原状态监控(查看事件查看器)
    MOSS常用部署命令stsadm (转)
    Linux系统常用命令
    VSTO Outlook 项目和文件夹的编程示例
    135 、137、139端口等主要用途
    WF编程 InvokeWebServiceActivity
    SQLSERVER2005 建立链接服务器
  • 原文地址:https://www.cnblogs.com/kbyd/p/3032273.html
Copyright © 2011-2022 走看看