雙調路徑node
思路:咱們能夠容易想到,經過不一樣的邊到達某個點的時間和金錢是不同的,這是難點。咱們發現點數n = 100,權值t,c = 100,若是咱們分別維護時間權值爲x時,到達該城市的最少金錢是多少,即d[城市][時間] = 金錢,由於 n = 100, t,c = 100,說明咱們須要維護 n*t 個點的值,則邊數爲 n * t * m = 3e6,咱們能夠用spfa解決。ios
#include <iostream> #include <cstdio> #include <algorithm> #include <set> #include <vector> #include <queue> using namespace std; #define ll long long #define pb push_back #define fi first #define se second const int INF = 2e4; struct node { int v, c, t; }; void SPFA(int n, int S, int T, vector<vector<node> >& E) { int _size = n * 100; vector<vector<bool> > vis(n + 1, vector<bool>(_size + 100, 0)); vector<vector<int> > d(n + 1, vector<int>(_size + 100, INF)); queue<pair<int, int> > que; vis[S][0] = true; d[S][0] = 0; que.push(make_pair(S, 0)); while (!que.empty()) { int u = que.front().fi; int w = que.front().se; que.pop(); vis[u][w] = false; for (auto e : E[u]) { if (w + e.t > n * 100) continue; //最多 n * 100 的時間消耗,沒有限制,則d[x][∞]會一直更新 if (d[e.v][w + e.t] > d[u][w] + e.c) { d[e.v][w + e.t] = d[u][w] + e.c; if (!vis[e.v][w + e.t]) { vis[e.v][w + e.t] = true; que.push(make_pair(e.v, w + e.t)); } } } } int ans = 0; int Min = INF; for (int i = 0; i <= n * 100; ++i) { if (d[T][i] < Min) { ++ans; Min = d[T][i]; } } printf("%d\n", ans); // cout << "this" << endl; } void solve() { int n, m, S, T; scanf("%d%d%d%d", &n, &m, &S, &T); vector<vector<node> > E(n + 1); int u, v, c, t; for (int i = 0; i < m; ++i) { scanf("%d%d%d%d", &u, &v, &c, &t); E[u].pb({ v, c, t }); E[v].pb({ u, c, t }); } SPFA(n, S, T, E); } int main() { // ios::sync_with_stdio(false); // cin.tie(0); cout.tie(0); // freopen("C:\\Users\\admin\\Desktop\\input.txt", "r", stdin); // freopen("C:\\Users\\admin\\Desktop\\output.txt", "w", stdout); solve(); // cout << "not error" << endl; return 0; }