• 《P4180 [BJWC2010]严格次小生成树》


    好久没码题了,码力好像有点下降。

    这题有结论可知:枚举没条不在最小生成树上的边,将这条边连上成环,那么就可以去掉环上的最长边(除了新加的这条)。

    因为这里是严格次小树,那么最长边就不能和这条新边相等,显然这条最长边只能 <= 新边,如果大于的话,那么最小生成树就可以有更小的。

    倍增维护最小值和次小值,如果光维护最小值,那么可能最长边 == 新边,维护次小值就能避免这点。

    u 写成了 i调试了n久。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef pair<int,int> pii;
    const int N = 1e5 + 5;
    const int M = 3e5 + 5;
    const LL Mod = 1e9 + 7;
    #define pi acos(-1)
    #define INF 1e18
    #define dbg(ax) cout << "now this num is " << ax << endl;
    namespace FASTIO{
        inline LL read(){
            LL x = 0,f = 1;char c = getchar();
            while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();}
            while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();}
            return x*f;
        }
    }
    using namespace FASTIO;
    
    int n,m,fa[N],f[N][20],dep[N],lg[N],tag[N];//ff - father
    LL Mx[N][20],Sx[N][20];
    struct Edge{
        int st,to,dis;
        bool operator < (const Edge a)const{
            return dis < a.dis;
        }
    }e[M];
    vector<Edge> G[N];
    void init(){
        for(int i = 1;i < N;++i) lg[i] = lg[i - 1] + ((1 << lg[i - 1]) == i);
    }
    int Find(int x){
        return x == fa[x] ? x : fa[x] = Find(fa[x]);
    }
    void dfs(int u,int ffa,int len){
        dep[u] = dep[ffa] + 1;
        f[u][0] = ffa,Mx[u][0] = len,Sx[u][0] = -INF;
        for(int i = 1;i <= lg[dep[u]];++i) {
            f[u][i] = f[f[u][i - 1]][i - 1];
            Mx[u][i] = max(Mx[u][i - 1],Mx[f[u][i - 1]][i - 1]);
            Sx[u][i] = max(Sx[u][i - 1],Sx[f[u][i - 1]][i - 1]);
            if(Mx[u][i - 1] > Mx[f[u][i - 1]][i - 1]) Sx[u][i] = max(Sx[u][i],Mx[f[u][i - 1]][i - 1]);
            else if(Mx[u][i - 1] < Mx[f[u][i - 1]][i - 1]) Sx[u][i] = max(Sx[u][i],Mx[u][i - 1]); 
        }
        for(auto v : G[u]) if(v.to != ffa) dfs(v.to,u,v.dis);
    }
    LL solve(int x,int y,int up){
        if(dep[x] < dep[y]) swap(x,y);
        LL ans = -1;
        while(dep[x] > dep[y]){
            int step = lg[dep[x] - dep[y]] - 1;
            if(Mx[x][step] != up) ans = max(ans,Mx[x][step]);
            else ans = max(ans,Sx[x][step]);
            x = f[x][step];
        }
        if(x == y) return ans;
        for(int i = lg[dep[x]] - 1;i >= 0;--i){
            if(f[x][i] != f[y][i]){
                if(Mx[x][i] != up) ans = max(ans,Mx[x][i]);
                else ans = max(ans,Sx[x][i]);
                if(Mx[y][i] != up) ans = max(ans,Mx[y][i]);
                else ans = max(ans,Sx[y][i]);
                x = f[x][i],y = f[y][i];
            }
        }
        if(x == y) return ans;
        if(Mx[x][0] != up) ans = max(Mx[x][0],ans);
        if(Mx[y][0] != up) ans = max(Mx[y][0],ans);
        return ans;
    }
    int main()
    {
        init();
        n = read(),m = read();
        for(int i = 1;i <= n;++i) fa[i] = i;
        LL sum = 0;
        for(int i = 1;i <= m;++i){
            e[i].st = read(),e[i].to = read(),e[i].dis = read();
        }
        sort(e + 1,e + m + 1);
        for(int i = 1;i <= m;++i){
            int xx = Find(e[i].st),yy = Find(e[i].to);
            if(xx != yy){
                fa[xx] = yy;
                G[e[i].st].push_back(Edge{e[i].st,e[i].to,e[i].dis});
                G[e[i].to].push_back(Edge{e[i].to,e[i].st,e[i].dis});
                tag[i] = 1;
                sum += e[i].dis;
            }
        }
        dfs(1,0,0);
        LL ans = INF;
        for(int i = 1;i <= m;++i){
            if(tag[i] == 1) continue;
            LL temp = solve(e[i].st,e[i].to,e[i].dis);
            //printf("x is %d y is %d tmp is %lld
    ",e[i].st,e[i].to,temp);
            ans = min(ans,sum - temp + e[i].dis);
        }
        printf("%lld
    ",ans);
        system("pause");
        return 0;
    }
    View Code
  • 相关阅读:
    Sum Root to Leaf Numbers 解答
    459. Repeated Substring Pattern
    71. Simplify Path
    89. Gray Code
    73. Set Matrix Zeroes
    297. Serialize and Deserialize Binary Tree
    449. Serialize and Deserialize BST
    451. Sort Characters By Frequency
    165. Compare Version Numbers
    447. Number of Boomerangs
  • 原文地址:https://www.cnblogs.com/zwjzwj/p/14277896.html
Copyright © 2020-2023  润新知