萌新MST求调
查看原帖
萌新MST求调
560516
喵仔牛奶楼主2022/8/23 15:32

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;
}
2022/8/23 15:32
加载中...