1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
| #include <iostream> #include <cstring> #include <algorithm> #include <queue>
using namespace std;
const int N = 510, M = 100010 * 2, INF = 1e6;
int n, m; int h[N], e[M], f[M], w[M], ne[M], idx; int dist[N][1010]; bool st[N][1010];
struct Node{ int x, y, v; bool operator<(const Node& t) const { return v > t.v; } };
void add(int t, int a, int b, int c) { e[idx] = b, f[idx] = t, w[idx] = c, ne[idx] = h[a], h[a] = idx ++; }
void dijkstra() { priority_queue<Node> heap; memset(dist, 0x3f, sizeof dist); heap.push({1, 0, 0}); dist[1][0] = 0; while(heap.size()) { auto t = heap.top(); heap.pop(); if (st[t.x][t.y]) continue; st[t.x][t.y] = true; for (int i = h[t.x]; ~i; i = ne[i]) { int x = e[i], y = t.y; if (f[i]) { y += w[i]; if (y <= 1000) { if (dist[x][y] > t.v - t.y * t.y + y * y) { dist[x][y] = t.v - t.y * t.y + y * y; if (dist[x][y] <= INF) { heap.push({x, y, dist[x][y]}); } } } } else { if (dist[x][0] > t.v + w[i]) { dist[x][0] = t.v + w[i]; if (dist[x][0] <= INF) { heap.push({x, 0, dist[x][0]}); } } } } } }
int main() { scanf("%d%d", &n, &m); memset(h, -1, sizeof h); while(m --) { int t, a,b, c; scanf("%d%d%d%d", &t, &a, &b, &c); add(t,a, b, c),add(t, b, a, c); } dijkstra(); int res = INF; for (int i = 0; i <= 1000; i ++) res = min(res, dist[n][i]); printf("%d\n", res); return 0; }
|