rt,思路是跑MST,然后在树剖MST跑ST表RMQ,求调qwq
#include <bits/stdc++.h>
#define int long long
using namespace std;
typedef long long ll;
const int N = 2e5 + 5, rt = 1, mod = 1e9 + 7;
struct edge {
ll u, v, w;
bool operator < (const edge& x) const {
return w < x.w;
}
} e[N << 1];
ll fa[N], lg[N], f[N][32], s[N], t[N], w[N];
ll cnt, n, m, u, v, ans, sum;
namespace MST {
struct edge {
ll to, w, next;
} e[N << 1];
ll w[N], head[N], fa[N], id[N], siz[N], top[N], depth[N], son[N];
int edge_cnt, cnt;
ll query(int l, int r) {
int k = lg[r - l + 1], p = 1 << k;
return max(f[l][k], f[r - p + 1][k]);
}
void dfs1(int u, int f, int dep) {
fa[u] = f, siz[u] = 1, depth[u] = dep;
for (int i = head[u]; i; i = e[i].next) {
int v = e[i].to;
if (v == f) continue;
w[v] = e[i].w, dfs1(v, u, dep + 1);
if (siz[v] > siz[son[u]])
son[u] = v;
siz[u] += siz[v];
}
}
void dfs2(int u, int topf) {
id[u] = ++ cnt, f[cnt][0] = w[u], top[u] = topf;
if (!son[u]) return;
dfs2(son[u], topf);
for (int i = head[u]; i; i = e[i].next) {
int v = e[i].to;
if (v == son[u] || v == fa[u]) continue;
dfs2(v, v);
}
}
ll qRange(int u, int v) {
ll ans = 0;
while (top[u] != top[v]) {
if (depth[top[u]] < depth[top[v]]) swap(u, v);
ans = max(ans, query(id[top[u]], id[u])), u = fa[top[u]];
}
if (depth[u] > depth[v]) swap(u, v);
return max(ans, query(id[u] + 1, id[v]));
}
void add(int u, int v, int w) {
e[++ edge_cnt].to = v;
e[edge_cnt].w = w;
e[edge_cnt].next = head[u];
head[u] = edge_cnt;
}
}
int find(int x) {
return fa[x] == x ? x : fa[x] = find(fa[x]);
}
void Kruskal() {
sort(e + 1, e + 1 + m);
for (int i = 1; i <= m; i ++) {
int fu = find(e[i].u), fv = find(e[i].v);
if (fu != fv) {
fa[fv] = fu, ans += e[i].w, sum ++;
MST::add(e[i].u, e[i].v, e[i].w), MST::add(e[i].v, e[i].u, e[i].w);
}
if (sum == n - 1) break;
}
}
void add(int u, int v, int w) {
e[++ cnt].u = u;
e[cnt].v = v;
e[cnt].w = w;
}
signed main() {
cin >> n >> m;
for (int i = 1; i <= m; i ++)
cin >> s[i] >> t[i] >> w[i], add(s[i], t[i], w[i]);
for (int i = 1; i <= n; i ++) fa[i] = i;
for (int i = 2; i <= n; i ++) lg[i] = lg[i / 2] + 1;
Kruskal(), MST::dfs1(1, 0, 1), MST::dfs2(1, 1);
for (int j = 1; j <= lg[n] + 1; j ++)
for (int i = 1; i + (1 << j) - 1 <= n; i ++)
f[i][j] = max(f[i][j - 1], f[i + (1 << j - 1)][j - 1]);
for (int i = 1; i <= m; i ++)
cout << ans - MST::qRange(s[i], t[i]) + w[i] << '\n';
return 0;
}