社区讨论

93pts wa on #5 玄关求条

P4180[BJWC2010] 严格次小生成树参与者 2已保存回复 2

讨论操作

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

当前回复
2 条
当前快照
1 份
快照标识符
@mhqm828g
此快照首次捕获于
2025/11/09 02:25
4 个月前
此快照最后确认于
2025/11/09 02:25
4 个月前
查看原帖
CPP
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define usd unsigned
#define el cout << '\n'
#define lowbit(x) (x & (-x))
const int ranmod = 1e7;
#define random ((rand() * rand()) % ranmod)
#define AC return 
#define AK return 0
#define YS cout << "YES"
#define NO cout << "NO"
#define Ys cout << "Yes"
#define No cout << "No"
#define ys cout << "yes"
#define no cout << "no"
#define ls(i) ch[i][0]
#define rs(i) ch[i][1]
#define debug(num) cerr << #num << ' ' << num << '\n'
#define pii pair <int, int> 
// void init();
void main_();
signed main() {
	ios :: sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	// freopen(".in", "r", stdin);
	// freopen(".out", "w", stdout);
	int t = 1;
	// cin >> t;
	while(t--) {
		// init();
		main_();
	}
	AK;
}
const int mod = 95225987, maxn = 3 * 1e5 + 18;

int n, m, ans = 0, answer = 1e18, dp[maxn][33], nxt[maxn][33], dep[maxn];
bool used[maxn];
vector <pii> vec[maxn];

int fa[maxn];
int find(int x) {
    if(fa[x] == x) return x;
    else {
        fa[x] = find(fa[x]);
        return fa[x];
    }
}
void merge(int a, int b) {
    fa[find(a)] = fa[find(b)];
}

struct edge {
    int u, v, w;
}e[maxn];
bool operator <(edge a, edge b) {
    return a.w < b.w;
}

void dfs(int x, int from, int w) {
    dep[x] = dep[from] + 1;
    nxt[x][0] = from, dp[x][0] = w;
    for(int i = 1; i <= 30; i++) {
        nxt[x][i] = nxt[nxt[x][i - 1]][i - 1];
        dp[x][i] = max(dp[x][i - 1], dp[nxt[x][i - 1]][i - 1]);
    }
    for(auto tmp : vec[x]) {
        int to = tmp.first, ww = tmp.second;
        if(to == from) continue;
        dfs(to, x, ww);
    }
}

int lca(int u, int v, int pos) {
    if(u == v) return 0;
    int res = -1;
    if(dep[u] > dep[v]) swap(u, v); // dep[u] < dep[v]
    if(dep[u] != dep[v]) {
        for(int i = 30; i >= 0; i--) if(dep[u] <= dep[nxt[v][i]]) {
            if(dp[v][i] < pos) res = max(res, dp[v][i]);
            v = nxt[v][i];
        }
    }
    if(u == v) AC res;
    for(int i = 30; i >= 0; i--) {
        if(nxt[u][i] != nxt[v][i]) {
            if(dp[v][i] < pos) res = max(res, dp[v][i]); 
            if(dp[u][i] < pos) res = max(res, dp[u][i]); 
            u = nxt[u][i], v = nxt[v][i];
        }
    }
    if(dp[u][0] < pos) res = max(res, dp[u][0]);
    if(dp[v][0] < pos) res = max(res, dp[v][0]);
    return res;
}

void main_() {
	cin >> n >> m;
    for(int i = 1; i <= n; i++) fa[i] = i;
    for(int i = 1; i <= m; i++) {
        int u, v, w;
        cin >> u >> v >> w;
        if(v > u) swap(u, v); // u < v
        e[i].u = u, e[i].v = v, e[i].w = w;
    }
    sort(e + 1, e + m + 1);
    int cnt = 0;
    for(int i = 1; i <= m; i++) {
        int u, v, w;
        u = e[i].u, v = e[i].v, w = e[i].w;
        if(find(u) == find(v)) continue;
        ans += w;
        merge(u, v);
        vec[u].push_back({v, w});
        vec[v].push_back({u, w});
        used[i] = true;
        cnt++;
        if(cnt == n - 1) break;
    }
    // debug(1);
    // dep[0] = 0;
    dfs(1, 1, 0);
    for(int i = 1; i <= m; i++) {
        if(used[i] || e[i].v == e[i].u) continue;
        int cur = lca(e[i].u, e[i].v, e[i].w), tmp = e[i].w - cur;
        debug(tmp), debug(cur);
        if(tmp != 0 && cur != -1) answer = min(answer, tmp);
    }
    // debug(ans);
    cout << ans + answer; el;
}

回复

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

正在加载回复...