ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

P4180 [BJWC2010]严格次小生成树

2020-09-25 20:02:05  阅读:254  来源: 互联网

标签:ll ret tq m1 BJWC2010 m2 P4180 生成 dis


P4180 BJWC2010严格次小生成树

先求一遍最小生成树。然后枚举加入哪条边,然后找这两个端点的LCA,记录路径上的最大值和严格次大值(我用了一种偷懒的方法,不过能过)。为什么记录严格次大值?因为我们需要注意最大值等于你加入的边的情况。

/*
Name: P4180
Copyright: NO
Author: Gensokyo_Alice
Date: 25/9/20 17:46
Description:
*/
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <set>
#include <map>

using namespace std;

typedef long long ll;
const ll MAXN = 1e6+10;
const ll INF = 0x3f3f3f3f3f3f3f3f;

struct edge {
    ll nt, to, v;
} E[MAXN];

struct edg {
    ll x, y, v;
    friend bool operator < (edg a, edg b) {
        return a.v < b.v;
    }
} e[MAXN];

struct zt {
    ll m1, m2, n;
};

ll q[4], tq, N, M, vis[MAXN], fa[MAXN], W, head[MAXN], cnt = -1, siz[MAXN], dep[MAXN], f[MAXN][22], dis[MAXN][2][22];

zt lca(ll, ll);
void add(ll, ll, ll);
void dfs(ll, ll);
ll find_(ll);
void krus();
void onion(ll, ll);

int main() {
    memset(head, -1, sizeof(head));
	ios::sync_with_stdio(false);
	#ifdef ZZCAKIOI
	#endif
    cin >> N >> M;
    for (ll i = 1; i <= M; i++) cin >> e[i].x >> e[i].y >> e[i].v;
    for (ll i = 1; i <= N; i++) fa[i] = i, siz[i] = 1;
    krus();
    dfs(1, 0);
    ll ans = INF;
    for (ll i = 1; i <= M; i++) {
        if (vis[i]) continue;
        zt now = lca(e[i].x, e[i].y);
        if (e[i].v == now.m1) ans = min(W - now.m2 + e[i].v, ans);
        else ans = min(W - now.m1 + e[i].v, ans);
    }
    cout << ans << '\n';
	return 0;
}

zt lca(ll x, ll y) {
    zt ret = {0, 0, 0};
    if (dep[x] < dep[y]) swap(x, y);
    ll di = dep[x] - dep[y];
    for (ll i = 20; ~i; i--) {
        if ((di >> i) & 1) {
            q[0] = dis[x][0][i], q[1] = dis[x][1][i];
            q[2] = ret.m1, q[3] = ret.m2;
		    sort(q, q+4);
		    tq = unique(q, q+4) - q;
            ret.m1 = q[tq-1], ret.m2 = q[tq-2];
            x = f[x][i];
        }
    }
    if (x == y) return ret;
    for (ll i = 20; ~i; i--) {
        if (f[x][i] != f[y][i]){
            q[0] = dis[x][0][i], q[1] = dis[x][1][i];
            q[2] = ret.m1, q[3] = ret.m2;
		    sort(q, q+4);
		    tq = unique(q, q+4) - q;
		    ret.m1 = q[tq-1], ret.m2 = q[tq-2];
            q[0] = ret.m1, q[1] = ret.m2;
            q[2] = dis[y][0][i], q[3] = dis[y][1][i];
		    sort(q, q+4);
		    tq = unique(q, q+4) - q;
            ret.m1 = q[tq-1], ret.m2 = q[tq-2];
            x = f[x][i], y = f[y][i];
        }
    }
    q[0] = dis[x][0][0], q[1] = dis[x][1][0];
    q[2] = ret.m1, q[3] = ret.m2;
    sort(q, q+4);
    tq = unique(q, q+4) - q;
    ret.m1 = q[tq-1], ret.m2 = q[tq-2];
    q[2] = dis[y][0][0], q[3] = dis[y][1][0];
    q[1] = ret.m1, q[0] = ret.m2;
    sort(q, q+4);
    tq = unique(q, q+4) - q;
    ret.m1 = q[tq-1], ret.m2 = q[tq-2];
    return ret;
}

void dfs(ll n, ll ff) {
    dep[n] = dep[ff] + 1;
    f[n][0] = ff;
    for (ll i = 1; i <= 20; i++) {
        f[n][i] = f[f[n][i-1]][i-1];
        q[0] = dis[n][0][i-1], q[1] = dis[n][1][i-1];
        q[2] = dis[f[n][i-1]][0][i-1], q[3] = dis[f[n][i-1]][1][i-1];
        sort(q, q+4);
        tq = unique(q, q+4) - q;
        dis[n][0][i] = q[tq-1], dis[n][1][i] = q[tq-2];
    }
    for (ll i = head[n]; ~i; i = E[i].nt) {
        ll v = E[i].to;
        if (v == ff) continue;
        else {
            dis[v][0][0] = E[i].v;
            dfs(v, n);
        }
    }
}

void krus() {
    sort(e+1, e+M+1);
    for (ll i = 1, ct = 0; i <= M && ct < N-1; i++) {
        ll fx = find_(e[i].x), fy = find_(e[i].y);
        if (fx != fy) {
            onion(fx, fy), ct++, W += e[i].v;
            add(e[i].x, e[i].y, e[i].v);
            add(e[i].y, e[i].x, e[i].v);
            vis[i] = 1;
        }
    }
}

void onion(ll x, ll y) {
    ll fx = find_(x), fy = find_(y);
    if (siz[fx] < siz[fy]) fa[fx] = fy, siz[fx] += siz[fy];
    else fa[fy] = fx, siz[fy] += siz[fx];
}

void add(ll x, ll y, ll v) {E[++cnt] = {head[x], y, v}, head[x] = cnt;}
ll find_(ll x) {return fa[x] == x ? x : fa[x] = find_(fa[x]);}

标签:ll,ret,tq,m1,BJWC2010,m2,P4180,生成,dis
来源: https://www.cnblogs.com/Gensokyo-Alice/p/13732184.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有