感觉不需要太多优化了。可能帮忙改改就过了。
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#include <ctime>
#include <set>
#define itset set<PLL>::iterator
using namespace std;
using LL = long long;
using PII = pair<int, int>;
using PLL = pair<LL, LL>;
const int N = 2010, M = N << 1;
const LL INF = 1e12;
LL dist[N]; int n, m;
set<PLL> s[N];
bool st[N];
namespace Edges {
int h[N], e[M], ne[M], idx; PLL w[M];
void add(int a, int b, LL w1, LL w2) {
e[ ++ idx] = b, ne[idx] = h[a], h[a] = idx;
w[idx] = {w1, w2};
}
} using namespace Edges;
struct Node {
int ver; LL a, b;
bool operator < (const Node &tmp)const {
return tmp.a * tmp.b < a * b;
}
};
bool check(int u, LL a, LL b) {
itset it = s[u].upper_bound({a, b});
for (itset i = s[u].begin(); i != it; ++ i)
if (i -> second <= b) return false;
return true;
}
void dij() {
priority_queue<Node, vector<Node>> q;
fill(dist + 1, dist + n + 1, INF);
s[1].insert({0, 0}); dist[1] = 0;
q.push({1, 0, 0});
while (q.size()) {
if ((double)clock() / CLOCKS_PER_SEC >= 2.45) return;
auto t = q.top(); q.pop();
int ver = t.ver, a = t.a, b = t.b;
for (int i = h[ver]; i; i = ne[i]) {
int j = e[i];
if (!check(j, a + w[i].first, b + w[i].second)) continue;
s[j].insert({a + w[i].first, b + w[i].second});
dist[j] = min(dist[j], (a + w[i].first) * (b + w[i].second));
q.push({j, a + w[i].first, b + w[i].second});
}
}
}
int main() {
scanf("%d%d", &n, &m);
while (m -- ) {
int a, b; LL w1, w2;
scanf("%d%d%lld%lld", &a, &b, &w1, &w2);
add(a, b, w1, w2), add(b, a, w1, w2);
}
dij();
for (int i = 2; i <= n; i ++ )
printf("%lld\n", dist[i] == INF ? -1 : dist[i]);
return 0;
}