From 5719bbc16c5ecba4ec20a18e37d52b18370c0bcd Mon Sep 17 00:00:00 2001 From: Bruno Freitas Tissei <bft15@inf.ufpr.br> Date: Thu, 6 Jun 2019 20:09:01 -0300 Subject: [PATCH] Add la4509 Signed-off-by: Bruno Freitas Tissei <bft15@inf.ufpr.br> --- algorithms/graph/bellman_ford.cpp | 11 ++- contests/Cadernaveis/LA4509.cpp | 110 ++++++++++++++++++++++++++++++ 2 files changed, 119 insertions(+), 2 deletions(-) create mode 100644 contests/Cadernaveis/LA4509.cpp diff --git a/algorithms/graph/bellman_ford.cpp b/algorithms/graph/bellman_ford.cpp index 301d3b2..cb5674f 100644 --- a/algorithms/graph/bellman_ford.cpp +++ b/algorithms/graph/bellman_ford.cpp @@ -2,6 +2,8 @@ /// /// Time: O(V * E) /// Space: O(V + E) +/// +/// Status: Tested (LA4509) struct BellmanFord { struct Edge { int u, v, w; }; @@ -11,12 +13,17 @@ struct BellmanFord { vector<Edge> graph; BellmanFord(int N) : - N(N), dist(N) {} + N(N), dist(N) + { init(); } void init() { fill(all(dist), inf); } + void add_edge(int u, int v, int w) { + graph.pb({ u, v, w }); + } + int run(int s, int d) { dist[s] = 0; @@ -30,7 +37,7 @@ struct BellmanFord { // there is one for (auto e : graph) if (dist[e.u] != inf && - dist[e.u] + w < dist[e.v]) + dist[e.u] + e.w < dist[e.v]) return -inf; return dist[d]; diff --git a/contests/Cadernaveis/LA4509.cpp b/contests/Cadernaveis/LA4509.cpp new file mode 100644 index 0000000..7ee3f60 --- /dev/null +++ b/contests/Cadernaveis/LA4509.cpp @@ -0,0 +1,110 @@ +#include <bits/stdc++.h> + +#define MAX 40 +#define EPS 1e-6 +#define MOD 1000000007 +#define inf 0x3f3f3f3f +#define llinf 0x3f3f3f3f3f3f3f3f + +#define fi first +#define se second +#define pb push_back +#define ende '\n' + +#define all(x) (x).begin(), (x).end() +#define rall(x) (x).rbegin(), (x).rend() +#define mset(x, y) memset(&x, (y), sizeof(x)) + +using namespace std; + +using ll = long long; +using ii = pair<int,int>; + +int dx[] = {-1, 1, 0, 0}; +int dy[] = {0, 0, 1, -1}; + +int mat[MAX][MAX]; + +struct BellmanFord { + struct Edge { int u, v, w; }; + + int N; + vector<int> dist; + vector<Edge> graph; + + BellmanFord(int N) : + N(N), dist(N) + { init(); } + + void init() { + fill(all(dist), inf); + } + + void add_edge(int u, int v, int w) { + graph.pb({ u, v, w }); + } + + int run(int s, int d) { + dist[s] = 0; + + for (int i = 0; i < N; ++i) + for (auto e : graph) + if (dist[e.u] != inf && + dist[e.u] + e.w < dist[e.v]) + dist[e.v] = dist[e.u] + e.w; + + for (auto e : graph) + if (dist[e.u] != inf && + dist[e.u] + e.w < dist[e.v]) + return -inf; + + return dist[d]; + } +}; + +int main() { + ios::sync_with_stdio(0); + cin.tie(0); + + int r, c; + while (cin >> c >> r && (c || r)) { + mset(mat, 0); + BellmanFord bell(r*c); + + int g; cin >> g; + for (int i = 0; i < g; ++i) { + int x, y; cin >> x >> y; + mat[y][x] = 1; + } + + int e; cin >> e; + for (int i = 0; i < e; ++i) { + int x1, y1; cin >> x1 >> y1; + int x2, y2; cin >> x2 >> y2; + int t; cin >> t; + + bell.add_edge(y1 * c + x1, y2 * c + x2, t); + mat[y1][x1] = 1; + } + + mat[r-1][c-1] = 1; + for (int i = 0; i < r; ++i) + for (int j = 0; j < c; ++j) + if (!mat[i][j]) + for (int k = 0; k < 4; ++k) { + int di = i + dx[k]; + int dj = j + dy[k]; + + if (di >= 0 && di < r && dj >= 0 && dj < c) + bell.add_edge(i*c + j, di*c + dj, 1); + } + + int ans = bell.run(0, (r-1)*c + (c-1)); + + if (ans == -inf) cout << "Never" << ende; + else if (ans == inf) cout << "Impossible" << ende; + else cout << ans << ende; + } + + return 0; +} -- GitLab