求帮忙卡常
查看原帖
求帮忙卡常
519384
Link_Cut_Y楼主2022/11/4 20:48

感觉不需要太多优化了。可能帮忙改改就过了。

#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;
}
2022/11/4 20:48
加载中...