結果

問題 No.2695 Warp Zone
ユーザー AerenAeren
提出日時 2024-03-22 22:12:34
言語 C++23
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 13 ms / 2,000 ms
コード長 4,103 bytes
コンパイル時間 3,527 ms
コンパイル使用メモリ 267,160 KB
実行使用メモリ 7,552 KB
最終ジャッジ日時 2024-03-22 22:12:39
合計ジャッジ時間 4,615 ms
ジャッジサーバーID
(参考情報)
judge15 / judge13
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
6,676 KB
testcase_01 AC 2 ms
6,676 KB
testcase_02 AC 2 ms
6,676 KB
testcase_03 AC 13 ms
7,552 KB
testcase_04 AC 12 ms
7,296 KB
testcase_05 AC 13 ms
7,296 KB
testcase_06 AC 12 ms
7,424 KB
testcase_07 AC 13 ms
7,552 KB
testcase_08 AC 2 ms
6,676 KB
testcase_09 AC 5 ms
6,676 KB
testcase_10 AC 2 ms
6,676 KB
testcase_11 AC 3 ms
6,676 KB
testcase_12 AC 7 ms
6,676 KB
testcase_13 AC 2 ms
6,676 KB
testcase_14 AC 8 ms
6,676 KB
testcase_15 AC 5 ms
6,676 KB
testcase_16 AC 2 ms
6,676 KB
testcase_17 AC 4 ms
6,676 KB
testcase_18 AC 10 ms
6,676 KB
testcase_19 AC 2 ms
6,676 KB
testcase_20 AC 9 ms
6,676 KB
testcase_21 AC 8 ms
6,676 KB
testcase_22 AC 5 ms
6,676 KB
testcase_23 AC 7 ms
6,676 KB
testcase_24 AC 2 ms
6,676 KB
testcase_25 AC 2 ms
6,676 KB
testcase_26 AC 2 ms
6,676 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

// #pragma GCC optimize("O3,unroll-loops")
#include <bits/stdc++.h>
// #include <x86intrin.h>
using namespace std;
#if __cplusplus >= 202002L
using namespace numbers;
#endif

template<class T>
struct dijkstra_dense{
	int n;
	T base_dist;
	vector<T> dist;
	vector<int> pv;
	vector<int> order;
	vector<int> pos;
	vector<int> root_of;
	vector<int> root;
	vector<int> depth;
	vector<int> was;
	dijkstra_dense(T base_dist = T{0}): base_dist(base_dist){ }
	void init(int n){
		this->n = n;
		dist.assign(n, base_dist);
		pv.assign(n, -1);
		order.clear();
		pos.assign(n, -1);
		root_of.assign(n, -1);
		root.clear();
		depth.assign(n, -1);
		was.assign(n, -2);
		done.assign(n, false);
		attempt = -1;
	}
	int attempt;
	vector<int> done;
	// act_greater(v, u): dist[v] has been updated to larger value by u
	// act_equal(v, u): dist[v] equals the length of shortest path to v through u
	// O(n^2)
	template<class U>
	void _run(const vector<vector<U>> &edge_length, const vector<int> &src, auto act_greater, auto act_equal){
		int n = (int)edge_length.size();
		for(auto u: src){
			if(was[u] == attempt) continue;
			was[u] = attempt;
			done[u] = false;
			dist[u] = base_dist;
			depth[u] = 0;
			root_of[u] = u;
			root.push_back(u);
			pv[u] = -1;
		}
		while(true){
			int u = -1;
			for(auto v = 0; v < n; ++ v) if(was[v] == attempt && !done[v] && (!~u || dist[u] > dist[v])) u = v;
			if(!~u) break;
			done[u] = true;
			pos[u] = (int)order.size();
			order.push_back(u);
			for(auto v = 0; v < n; ++ v) if(~edge_length[u][v]){
				if(was[v] != attempt || !done[v] && dist[u] + edge_length[u][v] < dist[v]){
					dist[v] = dist[u] + edge_length[u][v];
					was[v] = attempt;
					done[v] = false;
					depth[v] = depth[u] + 1;
					pv[v] = u;
					root_of[v] = root_of[u];
					act_greater(v, u);
				}
				else if(!done[v] && dist[u] + edge_length[u][v] == dist[v]) act_equal(v, u);
			}
		}
	}
	// Requires graph
	template<class Graph>
	void run(const Graph &g, const vector<int> &src, auto act_greater, auto act_equal){
		assert(g.n <= n);
		if(g.n == 0) return;
		for(auto u: src) assert(0 <= u && u < g.n);
		root.clear(), order.clear();
		++ attempt;
		vector edge_length(g.n, vector<typename Graph::Weight_t>(g.n, -1));
		for(auto u = 0; u < g.n; ++ u) for(auto id: g.adj[u]){
			if(g.ignore && g.ignore(id)) continue;
			assert(0 <= g.edge[id].cost);
			int v = g(u, id);
			edge_length[u][v] = ~edge_length[u][v] ? min(edge_length[u][v], g.edge[id].cost) : g.edge[id].cost;
		}
		_run(edge_length, src, act_greater, act_equal);
	}
	// Requires graph
	template<class Graph>
	void run(const Graph &g, const vector<int> &src){
		run(g, src, [&](int, int){  }, [&](int, int){  });
	}
	// edge_length = -1 implies no edge
	template<class U>
	void run(const vector<vector<U>> &edge_length, const vector<int> &src, auto act_greater, auto act_equal){
		int n = (int)edge_length.size();
		assert(n <= this->n);
		for(const auto &row: edge_length) for(auto w: row) assert(-1 <= w);
		for(auto u: src) assert(0 <= u && u < n);
		root.clear(), order.clear();
		++ attempt;
		_run(edge_length, src, act_greater, act_equal);
	}
	// edge_length = -1 implies no edge
	template<class U>
	void run(const vector<vector<U>> &edge_length, const vector<int> &src){
		run(edge_length, src, [&](int, int){  }, [&](int, int){  });
	}
	// Check if u is visited during the last dijkstra-like call.
	bool visited(int u) const{
		return was[u] == attempt;
	}
};

int main(){
	cin.tie(0)->sync_with_stdio(0);
	cin.exceptions(ios::badbit | ios::failbit);
	int nr, nc, n;
	cin >> nr >> nc >> n;
	vector<array<int, 4>> a(n + 2);
	a[1] = {nr - 1, nc - 1, nr - 1, nc - 1};
	for(auto &[p, q, r, s]: a | ranges::views::drop(2)){
		cin >> p >> q >> r >> s, -- p, -- q, -- r, -- s;
	}
	vector<vector<int>> adjm(n + 2, vector<int>(n + 2, -1));
	for(auto u = 0; u <= n + 1; ++ u){
		for(auto v = 0; v <= n + 1; ++ v){
			if(u != v){
				adjm[u][v] = abs(a[u][2] - a[v][0]) + abs(a[u][3] - a[v][1]) + 1;
			}
		}
	}
	dijkstra_dense<long long> D;
	D.init(n + 2);
	D.run(adjm, {0});
	cout << D.dist[1] - 1 << "\n";
	return 0;
}

/*

*/
0