基于从源到目的地的最短最长距离的问题

时间:2019-04-03 19:39:43

标签: c++ graph path-finding

公司希望为其半导体制造探索一些稀有元素。科学家使用一种工具探索该地区,以发现稀有元素。车辆只能在已修建道路的勘探区域内行驶。车辆无法在没有道路的未探索区域行驶。在当前情况下,稀有元素仅存在于勘探区。未开发区域不包含任何稀有元素。 提供方形区域供探索。道路用1表示,不存在道路的区域用0表示。稀有元素只会出现在已经探索过区域的道路上。车辆可以在四个方向上移动-上,下,左和右。 车辆到达稀有元素位置的最短路径称为“移动路径”。从最长距离到所有稀有元素的路径中最长的路径。 科学家需要建立一个研究中心,以使研究中心位于通往稀有元素的最长路径最短的位置。这称为最短最长距离。

例如,红色,蓝色和绿色区域表示稀有元素区域。 (2,2)表示为红色,(2,8)表示为蓝色,(7,8)表示为绿色。因此,存在三个稀有元素。 如果将研究中心建设在(4,4),则到红色稀有元素的距离将是4,到蓝色稀有元素的距离将是6,到绿色稀有元素的距离将是7。因此,最长距离将是7。 >

现在使用与上面相同的区域,如果在(4,5)构建研究中心,则到红色稀有元素的距离将是5,到蓝色稀有元素的距离将是5,到绿色稀有元素的距离将是6。最长距离为6。 因此,当研究中心建在(4,5)时,最长的距离将最短。最短最长距离的值将是6。这将是输出。 可能有多个位置,最短的最长距离可以相同。例如,如果研究中心建在(5,5),则最短最长距离仍为6。 因此,编写一个程序以找到最短最长距离。

约束: •提供的区域将是正方形区域,即NxN(其中5 <= N <= 20)。

•至少可以包含2个稀有元素,最多可以包含4个稀有元素,即2 <= C <= 4。

•道路用1代表,而道路面积用0代表。

•车辆只能在探索区域的道路上行驶。

•稀有元素只会在有路的地方出现。没有道路的地方将不会出现稀有元素。

•车辆可以向上,向下,向左和向右移动。

•稀有元素的起始索引被视为1。

输入:

•第一行将是测试用例的数量。第二行将指示区域面积(N)和稀有元素数量(C)。

接下来的C行将包含稀有元素的位置。

在那之后,N条线将提供区域详细信息,以告诉哪里有道路和不存在道路。

输出:

•输出#testcase,后跟空格,然后是最短最长距离。

样本输入:

5
5 2
4 3
3 4
1 1 0 0 0
1 1 0 0 0
1 1 1 1 1
1 1 1 0 1
1 1 1 1 1
8 2
5 6
6 4
1 1 1 1 1 1 0 0
1 1 1 1 1 1 1 0
1 1 0 1 0 1 1 0
1 1 1 1 0 1 1 0
1 1 1 1 1 1 1 0
1 1 1 1 1 1 1 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
10 3
8 2
5 3
7 1
0 0 0 1 1 1 1 1 1 0
1 1 1 1 1 1 1 1 1 0
1 0 0 1 0 0 0 0 1 0
1 1 1 1 1 1 1 1 1 1
1 1 1 1 0 1 0 0 1 1
1 1 1 1 0 1 0 0 1 1
1 1 1 1 0 1 0 0 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 0 0 1 0 0 1 1
1 1 1 1 1 1 1 1 1 1
15 4
11 15
15 9
1 2
14 3
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 0 1 1 1 1 1 1 1 1 1 1 1 0 1
1 0 1 0 0 0 1 0 0 0 0 1 1 0 1
1 0 1 0 0 0 1 0 0 0 0 1 1 0 1
1 0 1 1 1 1 1 1 1 1 1 1 1 1 1
1 0 1 0 0 0 1 0 0 0 0 1 1 0 1
1 0 1 0 0 0 1 1 1 1 1 1 1 1 1
1 0 1 0 0 0 1 0 0 0 0 1 1 0 1
1 0 1 0 0 0 1 0 0 0 0 1 1 0 1
1 0 1 0 0 0 1 0 0 0 0 1 1 0 1
1 0 1 0 0 0 1 0 0 0 0 1 1 0 1
1 0 1 0 0 0 1 0 0 0 0 1 1 0 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0 0 1 0 0 0 1 1 1 1 1 1 1 0 1
0 0 1 1 1 1 1 1 1 1 1 1 1 1 1
20 4
13 6
20 4
1 2
17 16
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0
1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0
1 0 1 0 0 0 0 0 0 0 1 0 0 1 1 0 0 0 0 0
1 0 1 0 0 0 0 0 0 0 1 0 0 1 1 0 0 0 0 0
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0
1 0 1 0 0 0 0 0 0 0 1 0 0 1 1 1 0 0 0 0
1 0 1 0 0 0 0 0 0 0 1 0 0 1 1 1 0 0 0 0
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 0 1 0 0 0 0 0 0 0 1 0 0 1 1 1 0 0 1 1
1 0 1 0 0 0 0 0 0 0 1 0 0 1 1 1 0 0 1 1
1 0 1 0 0 0 0 0 0 0 1 0 0 1 1 1 0 0 1 1
1 0 1 0 0 0 0 0 0 0 1 0 0 1 1 1 0 0 1 1
1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1
1 0 1 0 0 0 0 0 0 0 1 0 0 0 1 1 0 0 1 1
1 0 1 0 0 0 0 0 0 0 1 0 0 0 1 1 0 0 1 1
1 0 1 0 0 0 0 0 0 0 1 0 0 0 1 1 0 0 1 1
1 0 1 0 0 0 0 0 0 0 1 0 0 0 1 1 0 0 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0

样本输出:

#1 1
#2 2
#3 2
#4 12
#5 15

我尝试使用回溯方法解决此问题。它为我提供了#1和#2测试用例的正确输出,但在其余测试用例中陷入了无限循环。

#include<iostream>

#include<fstream>

using namespace std;

int a[22][22];
int x[4];
int y[4];
bool visit[22][22];
int N;
int ele; //Number of rare elements

void unvisit()
{
    for(int i=0;i<N;++i)
    {
        for(int j=0;j<N;++j)
        {
            visit[i][j]=false;
        }
    }
}

bool isSafe(int x, int y)
{
    if(x>=N || y>=N || x<0 || y<0 || a[x][y]==0 || visit[x][y]==true )
        return false;
    return true;
}
int min_distance(int x, int y,  int d_x, int d_y, int dis)
{
    //cout<<"x:"<<x<<" "<<"y:"<<y<<" "<<dis<<" "<<d_x<<" "<<d_y<<endl;
    int left=999,right=999,up=999,down=999;
    if(x==d_x && y==d_y)
    {
        //cout<<"MATCH:"<<dis<<endl;
        return dis;
    }
    //cout<<min_dis;
    visit[x][y]=true;


        if(isSafe(x,y+1))
            right=min_distance(x,y+1,d_x,d_y,dis+1);
        if(isSafe(x,y-1))
            left=min_distance(x,y-1,d_x,d_y,dis+1);
        if(isSafe(x+1,y))
            down=min_distance(x+1,y,d_x,d_y,dis+1);
        if(isSafe(x-1,y))
            up=min_distance(x-1,y,d_x,d_y,dis+1);

        visit[x][y]=false;

        return min(min(min(right,left),down),up);





}

int main()
{
    int d1=-999,d2=999;


    fstream myfile;

    myfile.open("Input.txt");



    myfile>>N>>ele;



    for(int i=0;i<ele;++i)
    {
        myfile>>x[i]>>y[i];
    }

    for(int i=0;i<N;++i)
    {
        for(int j=0;j<N;++j)
        {
            myfile>>a[i][j];
        }
    }

    for(int i=0;i<N;++i)
    {
        for(int j=0;j<N;++j)
        {

            if(a[i][j]==1)
            {
                d1=-999;
            for(int k=0;k<ele;++k)
            {
                //cout<<i<<" "<<j<<" "<<endl;


                unvisit();
                d1=max(d1,min_distance(i,j,x[k],y[k],0));

                //cout<<"x:"<<i<<" "<<"y:"<<j<<" "<<"d1:"<<d1<<endl;;

            }
            }

        d2=min(d2,d1);
        //cout<<"d2:"<<d2<<endl;




        }
    }

    cout<<d2<<endl;

    myfile.close();

    return 0;




}

有人可以告诉我为什么我的解决方案不起作用吗?谢谢!

1 个答案:

答案 0 :(得分:0)

逻辑是正确的。代码中没有错误。问题在于回溯要花费大量时间。当矩阵密集时,解决最小距离问题不是很合适。 BFS是解决此类问题的最佳方法。