diff --git a/algorithms/graph/bellman_ford.cpp b/algorithms/graph/bellman_ford.cpp index 301d3b2145a8a7788ae5410365170123ba5cd112..cb5674f01fe151fafa19f8026e1430377ec33eae 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 0000000000000000000000000000000000000000..7ee3f60e913ca112030591f6caf46b92243af3d1 --- /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; +}