2022“杭电杯”中国大学生算法设计超级联赛(5)1003 Slipper

建边需要一些技巧,不然会TLE。一种方式是在每个深度\(d\)新建一个点\(t_d(1\le d\le maxdep)\),对于每个深度为\(d\)的点 \(u_d\),从\(t_d\)\(u_d\)连一条有向边,再从\(u_d\)\(t_{d-k}\)\(t_{d+k}\)连有向边,最后跑一遍dij即可

#include<bits/stdc++.h>
using namespace std;

#define fr first
#define se second
#define et0 exit(0);
#define rep(i, a, b) for(int i = (int)(a); i <= (int)(b); i ++)
#define rrep(i, a, b) for(int i = (int)(a); i >= (int)(b); i --)
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);

typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, int> PLI;
typedef unsigned long long ULL;

const int INF = 0X3f3f3f3f, N = 2e6 + 10, M = 4 * N, MOD = 1e9 + 7;
const double eps = 1e-7, pi = acos(-1);

int n, k, p, start, ed;

int depth[N], maxdep;

int head[N], idx;

struct EGDE {
	int to, next, w;
} eg[M];

void add(int x, int y, int w) {
	eg[idx].to = y;
	eg[idx].next = head[x];
	eg[idx].w = w;
	head[x] = idx++;
}

void dfs(int cur, int fa, int dep) {
	depth[cur] = dep;
	maxdep = max(maxdep, dep);
	for (int i = head[cur]; ~i; i = eg[i].next) {
		int to = eg[i].to;
		if (to == fa) continue;
		dfs(to, cur, dep + 1);
	}
}

LL dis[N];
bool st[N];

void dij() {
	priority_queue<PLI, vector<PLI>, greater<PLI> > q;
	memset(dis, 0x3f, sizeof dis);
	memset(st, 0, sizeof st);
	dis[start] = 0;
	q.push({0ll, start});
	while (!q.empty()) {
		auto cur = q.top().se;
		q.pop();
		if (cur == ed) return;
		if (st[cur]) continue;
		st[cur] = 1;
		for (int i = head[cur]; ~i; i = eg[i].next) {
			int to = eg[i].to;
			if (dis[to] > dis[cur] + eg[i].w) {
				dis[to] = dis[cur] + eg[i].w;
				q.push({dis[to], to});
			}
		}
	}
	return;
}

void work() {
	idx = maxdep = 0;
	memset(head, -1, sizeof head);
	cin >> n;

	rep(i, 2, n) {
		int x, y, w;
		cin >> x >> y >> w;
		add(x, y, w);
		add(y, x, w);
	}

	cin >> k >> p >> start >> ed;
	dfs(1, 0, 1);

	rep(i, 1, n) {
		add(n + depth[i], i, p);
		if (depth[i] - k >= 1) add(i, n + depth[i] - k, 0);
		if (depth[i] + k <= maxdep) add(i, n + depth[i] + k, 0);
	}

	dij();
	cout << dis[ed] << endl;
}

int main() {
	IO
	int test = 1;
	cin >> test;

	while (test--) {
		work();
	}

	return 0;
}
posted @ 2022-08-03 13:45  xhy666  阅读(74)  评论(0)    收藏  举报