hdu4771 Stealing Harry Potter's Precious A*算法寻路

题目大意:
给定一个n*m的方格图,有障碍和K个目标(K<=4),求从某点出发经过所有目标的最短路线

解法:根据只有4个目标,可以先算出每个目标之间的距离,而后从出发点开始进行深搜即可。
对题目中带障碍的静态方格图,A*算法可以非常高效的求出两点之间最短距离。对于估值函数,可以计算较为高效的曼哈顿距离(x坐标之差绝对值加上y坐标之差绝对值之和),可以证明这样的估值函数得到的最终结果必定最优。


#pragma comment(linker, "/STACK:102400000,102400000")
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<sstream>
#include<stack>
#include<queue>
#include<fstream>
#include<algorithm>
#include<map>
#include<set>
#include<vector>
#include<functional>
#include<cmath>
#define CLR(x) memset(x,0,sizeof(x))
#define SETMAX(x) memset(x,0x3f,sizeof(x))
#define SETNO(x) memset(x,-1,sizeof(x))
#define ll long long
#define eps 3e-12
#define pow2(x) ((x)*(x))
#define forto(i,n) for(int i=0;i<n;i++)
#define for1to(i,n) for(int i=1;i<=n;i++)
#define VI vector<int>
using namespace std;
const double PI=acos(-1.0);
#define INF 0x3f3f3f3f
#define NINF 0xbfffffff

using namespace std;
int Map[111][111];
bool visit[111][111];
struct node
{
    int x;
    int y;
    int h;
    int g;
    int f;
    bool operator<(const node& ano) const
    {
        return f>ano.f;
    }
}st;
priority_queue<node> Aq;
int x[5],y[5];
int MinDis[5][5];
int Dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
int K;
int n,m;

bool in(int x,int y)
{
    if (x<0||y<0||x>=n||y>=m)
        return false;
    return true;
}

int Astar(int s,int t)
{
    CLR(visit);
    while(!Aq.empty())
        Aq.pop();
    st.x=x[s];
    st.y=y[s];
    st.g=0;
    st.h=abs(x[t]-x[s])+abs(y[t]-y[s]);
    st.f=st.g+st.h;
    visit[x[s]][y[s]]=true;
    Aq.push(st);
    while(!Aq.empty())
    {
        st=Aq.top();
        Aq.pop();
        if (st.x==x[t]&&st.y==y[t])
            return st.g;
        node st2;
        forto(i,4)
        {
            st2.x=st.x+Dir[i][0];
            st2.y=st.y+Dir[i][1];
            if (!in(st2.x,st2.y)||Map[st2.x][st2.y]||visit[st2.x][st2.y])
                continue;
            visit[st2.x][st2.y]=true;
            st2.h=abs(x[t]-st2.x)+abs(y[t]-st2.y);
            st2.g=st.g+1;
            st2.f=st2.h+st2.g;
            Aq.push(st2);
        }
    }
    return INF;
}

bool visit2[5];
int result;
void dfs(int prec,int dep,int res)
{
    if (dep==K)
    {
        result=min(result,res);
        return;
    }
    for(int i=1;i<=K;i++)
        if (!visit2[i]&&MinDis[prec][i]!=INF)
        {
            visit2[i]=true;
            dfs(i,dep+1,res+MinDis[prec][i]);
            visit2[i]=false;
        }
}

int main()
{
    ios_base::sync_with_stdio(false);
    while(cin>>n>>m,n||m)
    {
        CLR(Map);
        forto(i,n)
        {
            forto(j,m)
            {
                char t;
                cin>>t;
                if (t=='#')
                    Map[i][j]=1;
                if (t=='@')
                    x[0]=i,y[0]=j;
            }
        }
        cin>>K;
        for1to(i,K)
        {
            int tx,ty;
            cin>>tx>>ty;
            tx--,ty--;
            x[i]=tx,y[i]=ty;
        }
        forto(i,K+1)
            for(int j=i+1;j<=K;j++)
                MinDis[i][j]=MinDis[j][i]=Astar(i,j);

        CLR(visit2);
        result=
INF;

        visit2[0]=true;
        dfs(0,0,0);
        visit2[0]=false;
        if (result==INF)
            cout<<-1<<endl;
        else
            cout<<result<<endl;
    }
    return 0;
}

你可能感兴趣的:(hdu4771 Stealing Harry Potter's Precious A*算法寻路)