CCCPaste

Untitled

#include 
#include 
#include 
using namespace std;
const int maxn = 51;
int n, m;
char mat[maxn][maxn];
int shortest_path[maxn][maxn][501];
int dist_between_metro_stations[maxn][maxn][maxn][maxn];
void bfs(vector> & ms) {
    int di[] = {-1, 1, 0, 0};
    int dj[] = {0, 0, -1, 1};
    for(int i = 0; i < (int) ms.size(); i++) {
        vector> visited(n, vector(m, false));

        int si = ms[i].first;
        int sj = ms[i].second;
        
        queue q;
        q.push(si);
        q.push(sj);
        q.push(0);
        
        while(!q.empty()) {
            int ci = q.front();
            q.pop();
            int cj = q.front();
            q.pop();
            int dist = q.front();
            q.pop();
            
            if(mat[ci][cj] == 'M') {
                dist_between_metro_stations[si][sj][ci][cj] = dist;
            }
            for(int k = 0; k < 4; k++) {
                int ti = ci + di[k];
                int tj = cj + dj[k];
                
                if(ti >= 0 and ti < n and tj >= 0 and tj < m and !visited[ti][tj]) {
                    q.push(ti);
                    q.push(tj);
                    q.push(dist + 1);
                    visited[ti][tj] = true;
                }
            }
        }
    }

}

struct node {
    int ci, cj;
    int time, money;
    
    node() {}
    node(int _ci, int _cj, int _time, int _money) {
        ci = _ci;
        cj = _cj;
        time = _time;
        money = _money;
    }
    
    bool operator < (const node & tmp) const {
        if(money == tmp.money) {
            return time > tmp.time;
        }
        return money > tmp.money;
    }
};
int main() {
    int metro_stations, time_limit;
    cin >> n >> m >> metro_stations >> time_limit;
    
    vector> ms;
    
    int si, sj;
    int ei, ej;
    for(int i = 0; i < n; i++) {
        for(int j = 0; j < m; j++) {
            cin >> mat[i][j];
        
            if(mat[i][j] == 'T') {
                si = i;
                sj = j;
            }
            if(mat[i][j] == 'K') {
                ei = i;
                ej = j;
            }
            if(mat[i][j] == 'M') {
                ms.push_back(make_pair(i, j));
            }
            
        }
    }
    
    bfs(ms);
    
    for(int i = 0; i < n; i++) {
        for(int j = 0; j < m; j++) {
            for(int k = 0; k <= time_limit; k++) {
                shortest_path[i][j][k] = 2e9;
            }
        }
    }
    int di[] = {-1, 1, 0, 0};
    int dj[] = {0, 0, -1, 1};
    priority_queue pq;
    pq.push(node(si, sj, 0, 0));
    
    while(!pq.empty()) {
        node c = pq.top();
        pq.pop();
        
        if(c.ci == ei and c.cj == ej) {
            cout << c.money << endl;
            return 0;
        }
        
        if(mat[c.ci][c.cj] == 'M') {
            for(int i = 0; i < (int) ms.size(); i++) {
                int dist = dist_between_metro_stations[c.ci][c.cj][ms[i].first][ms[i].second];
                if(c.time + dist <= time_limit and c.money + 5 * dist < shortest_path[ms[i].first][ms[i].second][c.time + dist]) {
                    pq.push(node(ms[i].first, ms[i].second, c.time + dist, c.money + 5 * dist));
                    shortest_path[ms[i].first][ms[i].second][c.time + dist] = c.money + 5 * dist;
                }
            }
        }
        
        for(int k = 0; k < 4; k++) {
            int ti = c.ci + di[k];
            int tj = c.cj + dj[k];
            if(ti >= 0 and ti < n and tj >= 0 and tj < m and mat[ti][tj] != '#') {
                if(c.time + 5 <= time_limit and c.money < shortest_path[ti][tj][c.time + 5]) {
                    pq.push(node(ti, tj, c.time + 5, c.money));
                    shortest_path[ti][tj][c.time + 5] = c.money;
                }
                if(c.time + 2 <= time_limit and c.money + 1 < shortest_path[ti][tj][c.time + 2]) {
                    pq.push(node(ti, tj, c.time + 2, c.money + 1));
                    shortest_path[ti][tj][c.time + 2] = c.money + 1;
                }
            }
        }
    }
    cout << -1 << endl;

    return 0;

}