社区讨论
灵异事件之有输出且正确 但全RE
P2934[USACO09JAN] Safe Travel G参与者 5已保存回复 10
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 10 条
- 当前快照
- 1 份
- 快照标识符
- @m5vzx2b4
- 此快照首次捕获于
- 2025/01/14 12:51 去年
- 此快照最后确认于
- 2025/11/04 11:38 4 个月前
我的代码样例有输出正确,但提交结果全 。把 #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 条回复,欢迎继续交流。
正在加载回复...