二刷死亡悬棺
查看原帖
二刷死亡悬棺
1114241
vectorxyz楼主2024/9/26 21:23

rt,输出全是 0,用树剖做的。。鉴定为树剖部分写挂了,kruskal 是完好的

#include <bits/stdc++.h>

using namespace std;
typedef pair<int, int> PII;
const int N = 1e5 + 5;
int n, m;
int fa[N];
struct node
{
    int u, v, w;    
}g[N];
bool cmp(node a, node b){return a.w < b.w;}
int tot, _, ans0, ans;
bool vis[N];
int head[N], a[N], w[N], f[N], top[N], id[N], sz[N], son[N], dep[N];
struct Edge{int v, w, next;}e[N];
void add(int u, int v, int w) {e[++tot].v = v, e[tot].w = w, e[tot].next = head[u], head[u] = tot;}
struct Kruskal
{
    int find(int x)
    {
        if(f[x] == x) return x;
        else return f[x] = find(f[x]); 
    }
    void init(){
        for(int i = 1;i <= n;i ++ ) f[i] = i;
        for(int i = 1;i <= m;i ++ ) cin >> g[i].u >> g[i].v >> g[i].w;
    }
    void kruskal()
    {
        init();
        sort(g + 1, g + 1 + m, cmp);
        for(int i = 1;i <= m;i ++ ){
            int x = find(g[i].u), y = find(g[i].v);
            if(x == y) continue;
            add(g[i].u, g[i].v, g[i].w), add(g[i].v, g[i].u, g[i].w);
            f[y] = x;
            ans0 += g[i].w;
            vis[i] = 1;
            if(++_ == n - 1) break;
        }
    }
}kru;
struct Segment
{
    struct node
    {
        int l, r, maxn, mex;
    }tr[N << 2];
    int get(int a, int b, int c, int d)
    {
        int yexo[4] = {a, b, c, d};
        sort(yexo, yexo + 4, greater<int>());
        for(int i = 1;i < 4;i ++ ){
            if(yexo[i] != yexo[0]) return yexo[i];
        }
        return yexo[0];
    }
    void build(int u, int l, int r)
    {
        if(l == r){
            tr[u].maxn = a[l];
            return ;
        }
        int mid = (l + r) / 2;
        build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
        tr[u].maxn = max(tr[u << 1 | 1].maxn, tr[u << 1].maxn);
        tr[u].mex = get(tr[u << 1].mex, tr[u << 1 | 1].mex, tr[u << 1].maxn, tr[u << 1 | 1].maxn);
    }
    PII query(int u, int l, int r, int ll, int rr){
        if(rr < l || ll > r){ return make_pair(LONG_LONG_MIN, LONG_LONG_MIN);
        }
        if(ll <= l && r <= rr){
            return make_pair(tr[u].maxn, tr[u].mex);
        }
        int mid = (l + r) / 2;
        PII x = query(u << 1, l, mid, ll, rr), y = query(u << 1 | 1, mid + 1, r, ll, rr);
        return make_pair(max(x.first, y.first), get(x.first, y.first, x.second, y.second));
    }
}seg;
void dfs1(int u, int F, int deep){
    fa[u] = F;
    dep[u] = deep;
    sz[u] = 1;
    int maxn = -1;
    for(int i = head[u];i;i = e[i].next){
        int v = e[i].v;
        if(v == F) continue;
        w[v] = w[u] + e[i].w;
        dfs1(v, u, deep + 1);
        sz[u] += sz[v];
        if(sz[v] > maxn){
            maxn = sz[v];
            son[u] = v;
        }
    }
}
void dfs2(int u, int topf){
    top[u] = topf;
    id[u] = ++_;
    a[_] = w[u] - w[fa[u]];
    if(!son[u]) return ;
    dfs2(son[u], topf);
    for(int i = head[u];i;i = e[i].next){
        int v = e[i].v;
        if(v == son[u] || v == fa[u]) continue;
        dfs2(v, v);
    }
}

int Find(int x, int y, int v){
    int res = LONG_LONG_MIN;
    while(top[x] != top[y]){
        if(dep[top[x]] < dep[top[y]]) swap(x, y);
        PII k = seg.query(1, 1, n, id[top[x]], id[x]);
        res = max(res, ((k.first == v) ? k.second : k.first));
        x = fa[top[x]];
    }
    if(dep[x] > dep[y]) swap(x, y);
    PII k = seg.query(1, 1, n, id[x] + 1, id[y]);
    res = max(res, ((k.first == v) ? k.second : k.first));
    return res;
}
int main()
{
    cin >> n >> m;
    kru.kruskal();
    dfs1(1, 0, 1), dfs2(1, 1), seg.build(1, 1, n);
    for(int i = 1;i <= m;i ++ ){
        if(!vis[i]){
            int temp = ans0 - Find(g[i].u, g[i].v, g[i].w) + g[i].w;   
            if(ans > temp && temp != ans0 + e[i].w && temp > ans0){
                ans = temp;
            }
        }
    }cout << ans << endl;
    return 0;
}

2024/9/26 21:23
加载中...