#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; }