社区讨论

灵异事件之有输出且正确 但全RE

P2934[USACO09JAN] Safe Travel G参与者 5已保存回复 10

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
10 条
当前快照
1 份
快照标识符
@m5vzx2b4
此快照首次捕获于
2025/01/14 12:51
去年
此快照最后确认于
2025/11/04 11:38
4 个月前
查看原帖
RT.\text{RT.} 我的代码样例有输出正确,但提交结果全 RE\text{RE}。把 #1 下载一看:这不是样例吗? 抱着可能是数据太小的想法,把 #2 也下载来测试,同样运行正常有输出,并且对拍结果是:找不到差异
我人都傻了。比较小众的权值线段树的做法,求调。
CPP
#include<bits/stdc++.h>
#define M N << 6
#define mid ((pl + pr) >> 1)
const int N = 2e5 + 10, inf = 0x3f3f3f3f;
using namespace std;
int n, m, ans[N];
int fa[N], head[N], son[N], top[N], size[N], dep[N], tot, dis[N], pre[N];
bool vis[N];
struct edge {
	int from, next, to, w;
	bool operator ==(const edge &eg) const {
		return (from == eg.from && to == eg.to) || (from == eg.to && to == eg.from);
	}
} e[N << 1], E[N << 1], nt[N]; //e最短路树 E原图 nt非树边集
int Head[N], Tot;
struct node {
	int dis, num;
	bool operator < (const node &x) const {
		return x.dis < dis;
	}
};
priority_queue<node> q;
void Dijkstra() {
	for (int i = 1; i <= n; i++) dis[i] = inf;
	dis[1] = 0;
	q.push((node) {
		0, 1
	});
	while (!q.empty()) {
		node top = q.top();
		q.pop();
		int u = top.num;
		if (vis[u]) continue;
		vis[u] = 1;
		for (int i = Head[u]; i; i = E[i].next) {
			int v = E[i].to;
			if (dis[v] > dis[u] + E[i].w) {
				dis[v] = dis[u] + E[i].w;
				pre[v] = u;
				if (!vis[v]) q.push((node) {
					dis[v], v
				});
			}
		}
	}
}
void Add(int u, int v, int w) {
	E[++Tot].to = v;
	E[Tot].from = u;
	E[Tot].next = Head[u];
	E[Tot].w = w;
	Head[u] = Tot;
}
void add(int u, int v, int w) {
	e[++tot].to = v;
	e[tot].next = head[u];
	e[tot].w = w;
	head[u] = tot;
}
void dfs1(int u, int f) {
	fa[u] = f;
	dep[u] = dep[f] + 1;
	size[u] = 1;
	for (int i = head[u]; i; i = e[i].next) {
		int v = e[i].to;
		if (v == f) continue;
		dfs1(v, u);
		size[u] += size[v];
		if (size[son[u]] < size[v]) son[u] = v;
	}
}
void dfs2(int u, int t) {
	top[u] = t;
	if (!son[u]) return;
	dfs2(son[u], t);
	for (int i = head[u]; i; i = e[i].next) {
		int v = e[i].to;
		if (v == fa[u] || v == son[u]) continue;
		dfs2(v, v);
	}
}
int LCA(int u, int v) {
	while (top[u] != top[v]) {
		if (dep[top[u]] < dep[top[v]]) swap(u, v);
		u = fa[top[u]];
	}
	return dep[u] < dep[v] ? u : v;
}
struct tree {
	int sum, ls, rs;
} t[M];
int cnt, rt[N];
void pushup(int p) {
	t[p].sum = t[t[p].ls].sum + t[t[p].rs].sum;
}
void update(int &p, int pl, int pr, int pos, int k) {
	if (!p) p = ++cnt;
	if (pl == pr) {
		t[p].sum += k;
		return;
	}
	if (pos <= mid) update(t[p].ls, pl, mid, pos, k);
	else update(t[p].rs, mid + 1, pr, pos, k);
	pushup(p);
}
int merge(int u, int v, int pl, int pr) {
	if (!u || !v) return u + v;
	if (pl == pr) {
		t[u].sum += t[v].sum;
		return u;
	}
	t[u].ls = merge(t[u].ls, t[v].ls, pl, mid);
	t[u].rs = merge(t[u].rs, t[v].rs, mid + 1, pr);
	pushup(u);
	return u;
}
int query(int p, int pl, int pr) {
	if (!t[p].sum) return 0;
	if (pl == pr) return pl;
	if (t[t[p].ls].sum >= 1) return query(t[p].ls, pl, mid);
	else query(t[p].rs, mid + 1, pr);
}
void calc(int u, int f) {
	for (int i = head[u]; i; i = e[i].next) {
		int v = e[i].to;
		if (v == f) continue;
		calc(v, u);
		rt[u] = merge(rt[u], rt[v], 1, inf);
	}
	int res = query(rt[u], 1, inf);
	ans[u] = res ? res - dis[u] : -1;
}
int sz;
int main() {
	scanf("%d%d", &n, &m);
	int u, v, w;
	for (int i = 1; i <= m; i++) {
		scanf("%d%d%d", &u, &v, &w);
		Add(u, v, w);
		Add(v, u, w);
	}
	Dijkstra();
	for (int i = 1; i <= Tot; i++) {
		if (E[i].from == pre[E[i].to] || E[i].to == pre[E[i].from]) add(E[i].from, E[i].to, E[i].w);
		else if (!(E[i] == nt[sz])) nt[++sz] = E[i];
	}
	dfs1(1, 0);
	dfs2(1, 1);
	for (int i = 1; i <= sz; i++) {
		int u = nt[i].from, v = nt[i].to;
		int lca = LCA(u, v);
		int w = dis[u] + dis[v] + nt[i].w;
		update(rt[u], 1, inf, w, 1);
		update(rt[v], 1, inf, w, 1);
		update(rt[lca], 1, inf, w, -2);
	}
	calc(1, 0);
	for (int i = 2; i <= n; i++) printf("%d\n", ans[i]);
	return 0;
}

回复

10 条回复,欢迎继续交流。

正在加载回复...