School Competition Problem F: Portal (Dijkstra's Algorithm)

Question F: Portal

Time Limit: 1 Sec Memory Limit: 128 MB

Topic description

Gayu has a portal maze thumbnail, the '.' on the thumbnail represents an open space, and the '#' represents a wall. His current location is '@' and his destination is '$'. Starting from the starting point, the garfish can only move up and down, left and right, and cannot pass through or destroy walls. It takes a little stamina to walk one space each time. At the same time, there will be some one-way portals in the map, with capital letters AZ representing the starting point of the portal, and lowercase az representing the end of the portal. When the garfish can be in the grid of the portal, you can choose not to use the portal, and the place will be regarded as an open space. If you use the portal, you need to spend money, and you can immediately transfer from the uppercase letter to the lowercase letter corresponding to the letter without consuming physical strength, but there is no way to send it back again. Similarly, the lowercase letters can also be regarded as an empty space .

Gayu’s physical energy and resources are limited. He wants to know how much energy and money will be consumed when reaching the destination (the topic is guaranteed to be reachable) under the optimal route. The optimal route should ensure that the energy consumption is the least. The least physical, you should choose the route that costs the least.

enter

The first line is an integer T, representing the number of sample groups

The second line is two integers representing the row number r and the column number c of the thumbnail respectively (r ,c <= 100)

Next is a string of r lines of length c

The last line is 26 numbers, corresponding to the money that each kind of portal needs to spend

output

Two integers separated by spaces, the first is the stamina consumption and the second is the money consumption.

sample input

1
5 5
$.a##
.@##A
#....
.....
.....

1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

Sample output

20 

Analysis:
We used ordinary bfs at the beginning for this question, but the result was timed out. Later, we learned that we need to use Dijkstra's algorithm, because the edge weights are different...
I feel really stupid, a Dijkstra It took about a week of algorithm research to basically figure it out.
Here are the AC codes:
#include<bits/stdc++.h>
using namespace std;
typedef pair < int , int > P;
const  int N = 100 + 10 ;
const  int dx [] = {- 1 , 0 , 0 , 1 };
const  int dy [] = { 0 , - 1 , 1 , 0 };
char a [N] [N];
int d [N] [N];
int c [N] [N];
int m, n, start [ 2 ], dest [ 2 ];
int cost_a [ 155],pos_a[155][2];
bool ok(int x,int y)
{
    return x>=0&&x<=m-1&&y>=0&&y<=n-1&&a[x][y]!='#';
}
struct cmp
{
    bool operator()(const P& p1,const P& p2)const
    {
        int x=p1.first,y=p1.second,x2=p2.first,y2=p2.second;
        return d[x][y]>d[x2][y2]||(d[x][y]==d[x2][y2]&&c[x][y]>c[x2][y2]);
    }
};
void Dijkstra()
{
    memset(d,0x3f3f,sizeof d);
    memset(c,0x3f3f,sizeof c);
    d [dest [ 0 ]] [dest [ 1 ]] = c [dest [ 0 ]] [dest [ 1 ]] = 0 ;
    priority_queue<P,vector<P>,cmp > q;
    q.push(P(dest[0],dest[1]));
    while(!q.empty())
    {
        int x=q.top().first,y=q.top().second;
        q.pop();
        int dis=d[x][y],cost=c[x][y];
        if(dis>d[start[0]][start[1]]||(dis==d[start[0]][start[1]]&&cost>c[start[0]][start[1]]))
            continue;
        for(int i=0; i<4; ++i)
        {
            int x2=x+dx[i],y2=y+dy[i];
            if(ok(x2,y2)&&(d[x2][y2]>dis+1||(d[x2][y2]==dis+1&&c[x2][y2]>cost)))
            {
                d[x2][y2]=dis+1,c[x2][y2]=cost;
                q.push(P(x2,y2));
            }
        }
        if(islower(a[x][y]))
        {
            int x2=pos_a[a[x][y]][0],y2=pos_a[a[x][y]][1];
            if(d[x2][y2]>dis||(d[x2][y2]==dis&&c[x2][y2]>cost+cost_a[a[x][y]]))
            {
                d[x2][y2]=dis,c[x2][y2]=cost+cost_a[a[x][y]];
                q.push(P(x2,y2));
            }
        }
    }
}
intmain ()
{
    //freopen("i.txt","r",stdin);
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&m,&n);
        for(int i=0; i<m; ++i)
            for(int j=0; j<n; ++j)
            {
                char ch;
                scanf(" %c",&ch);
                if(ch=='$')
                    dest[0]=i,dest[1]=j;
                else if(ch=='@')
                    start[0]=i,start[1]=j;
                else if(isupper(ch))
                    pos_a[tolower(ch)][0]=i,pos_a[tolower(ch)][1]=j;
                a[i][j]=ch;
            }
        for(char ch='a'; ch<='z'; ++ch)
            scanf("%d",&cost_a[ch]);
        Dijkstra();
        printf("%d %d\n",d[start[0]][start[1]],c[start[0]][start[1]]);
    }
    return 0;
}
 

Editor: ltx

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325002938&siteId=291194637