Algorithm 为多个起始位置查找到终点的最短路径

Algorithm 为多个起始位置查找到终点的最短路径,algorithm,graph,Algorithm,Graph,有一个大小为N乘M的迷宫,有墙和走廊。迷宫里有金子,迷宫里也有一些人。任务是找出从某人到奖品的最短路径是什么,以及谁将获得奖品 如果只有一个人,我知道如何解决这个问题,但如果不止一个人,我就不知道如何解决 输入如下。在第一行N、M和Q(输入人数)。输入N行上的M个字符(.for roadway,#for wall)。然后在Q线上输入每个人的坐标 如果有人可以到达黄金,程序应输出最短路径的长度以及到达黄金的人(如果多人同时到达黄金,则其中任何一人都是正确的输出)。如果没有路径,程序应该输出-1。解

有一个大小为N乘M的迷宫,有墙和走廊。迷宫里有金子,迷宫里也有一些人。任务是找出从某人到奖品的最短路径是什么,以及谁将获得奖品

如果只有一个人,我知道如何解决这个问题,但如果不止一个人,我就不知道如何解决

输入如下。在第一行N、M和Q(输入人数)。输入N行上的M个字符(.for roadway,#for wall)。然后在Q线上输入每个人的坐标


如果有人可以到达黄金,程序应输出最短路径的长度以及到达黄金的人(如果多人同时到达黄金,则其中任何一人都是正确的输出)。如果没有路径,程序应该输出-1。

解决这个问题的最简单方法是从黄金开始,使用BFS(广度优先搜索)查找到任何人的最短路径。以下是我的实现:

#include<iostream>
#include<queue>
using namespace std;
const int MAX_N=100; //you didn't say the restrictions so I am going to leave it as a 100
int n,m,q;
char maze[MAX_N][MAX_N];
vector<pair<int,int> > p;
int len[MAX_N][MAX_N]; //stores if we have visited the node and the length to there
int main()
{
    cin>>n>>m>>q;
    for (int i=0;i<n;++i)
    {
        for (int j=0;j<m;++j)
        {
            cin>>maze[i][j];
            len[i][j]=-1;
        }
    }
    int x,y;
    for (int i=0;i<q;++i)
    {
        cin>>x>>y;
        --y;
        --x;
        p.push_back(make_pair(y,x));
        maze[y][x]='p';
    }
    /*
    You didn't say when we input the gold's coordinates, so I'm going to assume it is in the end.
    */
    cin>>x>>y;
    --y;
    --x;
    len[y][x]=0;
    queue<pair<int,int> > qu;
    qu.push(make_pair(y,x));
    while (!qu.empty())
    {
        y=qu.front().first;
        x=qu.front().second;
        qu.pop();
        if (maze[y][x]=='p')
        {
            //we have reached a person and just need to find which it is
            for (int i=0;i<q;++i)
            {
                if (p[i].first==y && p[i].second==x)
                {
                    cout<<len[y][x]<<" "<<i+1<<endl;
                    return 0;
                }
            }
        }
        if (y>0 && maze[y-1][x]!='#' && len[y-1][x]==-1)
        {
            len[y-1][x]=len[y][x]+1;
            qu.push(make_pair(y-1,x));
        }
        if (y<n-1 && maze[y+1][x]!='#' && len[y+1][x]==-1)
        {
            len[y+1][x]=len[y][x]+1;
            qu.push(make_pair(y+1,x));
        }
        if (x>0 && maze[y][x-1]!='#' && len[y][x-1]==-1)
        {
            len[y][x-1]=len[y][x]+1;
            qu.push(make_pair(y,x-1));
        }
        if (x<m-1 && maze[y][x+1]!='#' && len[y][x+1]==-1)
        {
            len[y][x+1]=len[y][x]+1;
            qu.push(make_pair(y,x+1));
        }
    }
    cout<<-1<<endl;
    return 0;
}
#包括
#包括
使用名称空间std;
常数int MAX_N=100//你没有说限制,所以我将把它作为100
int n,m,q;
字符迷宫[MAX_N][MAX_N];
向量p;
国际长度[MAX_N][MAX_N]//存储我们是否访问过该节点以及到达该节点的长度
int main()
{
cin>>n>>m>>q;
对于(int i=0;imaze[i][j];
len[i][j]=-1;
}
}
int x,y;
对于(inti=0;i>x>>y;
--y;
--x;
p、 向后推(形成一对(y,x));
迷宫[y][x]='p';
}
/*
你没有说我们什么时候输入黄金的坐标,所以我假设它最终是。
*/
cin>>x>>y;
--y;
--x;
len[y][x]=0;
队列区;
qu.push(使成对(y,x));
而(!qu.empty())
{
y=第一个曲前();
x=前()秒的质量;
qu.pop();
if(迷宫[y][x]='p')
{
//我们已经找到一个人,只需要找到他是谁

对于(int i=0;如果你只对所有人使用Dijkstra或w/e,我会太慢吗?@shole是的,可能有很多人。我同意@indjev99的答案,对于网格,只需从黄金中获得一个简单的BFS就足够了,这应该是从复杂性方面获得的最佳解决方案使用Djikstra的算法,但从黄金开始,你找到的第一个人h作为通往黄金的最短路径。@Fibbles是正确的,但由于网格是图的一个特例,每个边的成本=1,简单的带队列的BFS就足够了(我更容易编写代码)