結果
問題 | No.2328 Build Walls |
ユーザー |
|
提出日時 | 2023-06-13 15:59:12 |
言語 | D (dmd 2.109.1) |
結果 |
MLE
|
実行時間 | - |
コード長 | 4,644 bytes |
コンパイル時間 | 3,448 ms |
コンパイル使用メモリ | 195,388 KB |
実行使用メモリ | 525,820 KB |
最終ジャッジ日時 | 2024-06-22 01:12:49 |
合計ジャッジ時間 | 17,674 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 MLE * 1 |
other | AC * 27 TLE * 4 -- * 3 |
ソースコード
import std;// ダイクストラ// (H-2)*(W+1)の頂点をおいて、8方向に有向辺を張るvoid read(T...)(string S, ref T args) {auto buf = S.split;foreach (i, ref arg; args) {arg = buf[i].to!(typeof(arg));}}void read_array(T)(string S, ref T[] arg) {arg = S.split.to!(T[]);}void main () {int H, W; readln.read(H, W);int[][] A = new int[][](H-2, W);foreach (i; 0..H-2) {readln.read_array(A[i]);A[i] = 0 ~ A[i];}solve(H, W, A);}struct pair {int x;int y;}bool isValid (int[][] A, int x, int y) {if (x < 0 || y < 0 || A.length <= y || A[0].length <= x) {return false;}if (A[y][x] == -1) {return false;}return true;}void connectPath (ref Dijkstra!pair G, int[][] A, int x, int y) {int[] dx = [-1, 0, 1];int[] dy = [-1, 0, 1];foreach (i; 0..dx.length) {foreach (j; 0..dy.length) {if (i == 1 && j == 1) {continue;}if (isValid(A, x+dx[i], y+dx[j])) {G.input(pair(x, y), pair(x+dx[i], y+dy[j]), A[y+dy[j]][x+dx[i]]);}}}}void solve (int H, int W, int[][] A) {auto G = Dijkstra!pair();foreach (X; 0..cast(int)A[0].length) {foreach (Y; 0..cast(int)A.length) {if (A[Y][X] == -1) {continue;}connectPath(G, A, X, Y);}}long ans = long.max;G.calculate(pair(0, 0));foreach (Y2; 0..H-2) {if (pair(W, Y2) in G.node) {ans = min(ans, G.cost(pair(W, Y2)));//G.trace(pair(W, Y2)).writeln;//writeln(G.cost(pair(W, Y2)));}}if (ans == long.max) {writeln(-1);} else {writeln(ans);}}struct Dijkstra(T) {T[][T] graph;long[T][T] weight;struct dijkstra_pair {long distance;T path;T vertex;}dijkstra_pair[T] node;private bool is_calculated = false;// 頂点の型Tであるグラフの辺と重みを受け取るvoid input (T u, T v, long w) {graph[u] ~= v;weight[u][v] = w;node[u] = dijkstra_pair(long.max, u, u);node[v] = dijkstra_pair(long.max, v, v);}// ダイクストラのアルゴリズムに基づいて頂点startからの(連結成分の)最小重みを求めるvoid calculate (T start) {if (start !in node) {stderr.writeln("Fatal error in dijkstra.calculate(T start) : This vertex is not in the graph!");return;}// 以前の計算のリセットif (is_calculated) {foreach (ref x; node) {x.distance = long.max;x.path = x.vertex;}}node[start].distance = 0;node[start].path = start;// 優先度付きキューの宣言BinaryHeap!(Array!dijkstra_pair, "b.distance < a.distance") PQueue;PQueue.insert(node[start]);int count = 0;while (!PQueue.empty) {auto begin = PQueue.front; PQueue.removeFront;if (node[begin.vertex].distance < begin.distance) {continue;}if (begin.vertex in graph) {foreach (ref x; graph[begin.vertex]) {if (node[begin.vertex].distance + weight[begin.vertex][x] < node[x].distance) {node[x].distance = node[begin.vertex].distance + weight[begin.vertex][x];node[x].path = begin.vertex;PQueue.insert(node[x]);}}}}is_calculated = true;}// 経路復元T[] trace (T end) {DList!T Q;T way = end;while (node[way].path != way) {Q.insertFront(way);way = node[way].path;}Q.insertFront(way);T[] ret;while (!Q.empty) {ret ~= Q.front; Q.removeFront;}return ret;}// 頂点endへの最小重みを出力 パスが存在しなければlong.maxを返す。long cost (T end) {if (end !in node) {stderr.writeln("Fatal error in dijkstra.cost(T end) : This vertex is not in the graph!");return long.max;}if (!is_calculated) {stderr.writeln("Costs are not calculatd. Do \"dijkstra.calculate(T start)\" first.");return long.max;}return node[end].distance;}}