zoukankan      html  css  js  c++  java
  • 609E- Minimum spanning tree for each edge

    Connected undirected weighted graph without self-loops and multiple edges is given. Graph contains n vertices and m edges.

    For each edge (u, v) find the minimal possible weight of the spanning tree that contains the edge (u, v).

    The weight of the spanning tree is the sum of weights of all edges included in spanning tree.

    Input

    First line contains two integers n and m (1 ≤ n ≤ 2·105, n - 1 ≤ m ≤ 2·105) — the number of vertices and edges in graph.

    Each of the next m lines contains three integers ui, vi, wi (1 ≤ ui, vi ≤ n, ui ≠ vi, 1 ≤ wi ≤ 109) — the endpoints of the i-th edge and its weight.

    Output

    Print m lines. i-th line should contain the minimal possible weight of the spanning tree that contains i-th edge.

    The edges are numbered from 1 to m in order of their appearing in input.

    Examples

    Input
    5 7
    1 2 3
    1 3 1
    1 4 5
    2 3 2
    2 5 3
    3 4 2
    4 5 4
    Output
    9
    8
    11
    8
    8
    8
    9

    次小生成树模板:
    lca+倍增+最小生成树
    #define eps 1e-6
    #define ll long long
    #define pii pair<int, int>
    #define pb push_back
    #define mp make_pair
    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<queue>
    #include<algorithm>
    //#pragma comment(linker, "/STACK:1024000000,1024000000")
    using namespace std;
    const int N = 200100;
    //*************************
    int n, m;
    //kruscal
    struct tree
    {
        int a,b,w;
    } p[N],s[N];
    int p1[N];
    int rk1[N];
    //倍增
    int fa[N][20], max_e[N][20], dep[N];
    //lca
    struct edge
    {
        int to, nxt,w;
    } e[N<<1];
    int fst[N], tot;
    struct query
    {
        int to,nxt;
        int idx;
    } Q[N<<1];
    int h[N],tt;
    int p2[N],rk2[N];
    int acr[N], ans[N];
    bool vis[N];
    //************************
    void CLS()
    {
        tot = 0;
        memset(fst,-1,sizeof(fst));
        tt = 0;
        for(int i=1; i<=n; i++)p1[i]=i,p2[i]=i;
        memset(h,-1,sizeof(h));
    }
    void add(int u,int v,int w)
    {
        e[++tot].to = v;
        e[tot].w = w;
        e[tot].nxt = fst[u];
        fst[u] = tot;
    }
    void add_Q(int u,int v,int idx)
    {
        Q[++tt].to = v;
        Q[tt].nxt = h[u];
        Q[tt].idx = idx;
        h[u] = tt;
    }
    //kruscal
    bool cmp(tree x,tree y)
    {
        return x.w<y.w;
    }
    int find_p(int x)
    {
        return x == p1[x] ? x : p1[x]=find_p(p1[x]);
    }
    void uone1(int x,int y)
    {
        int t1=find_p(x);
        int t2=find_p(y);
        if(t1!=t2)
        {
            if(rk1[t1]>rk1[t2])p1[t2]=t1;
            else p1[t1]=t2;
            if(rk1[t1]==rk1[t2])rk1[t2]++;
        }
    }
    ll kruscal()
    {
        ll res = 0;
        sort(p+1, p+m+1, cmp);
        int cnt=0;
        for (int i = 1; i <= m; i++)
        {
            int x=p[i].a;
            int y=p[i].b;
            int w=p[i].w;
            if(find_p(x)!=find_p(y))
            {
                cnt++;
                uone1(x,y);
                res+=w;
                add(x,y,w);
                add(y,x,w);
                if(cnt==n-1)break;
            }
        }
        return res;
    }
    
    //倍增
    void init_fa(int u, int p, int w)
    {
        dep[u] = dep[p] + 1;
        fa[u][0] = p;
        max_e[u][0] = w;
        for (int i = 1; fa[u][i-1]; i++)
        {
            fa[u][i] = fa[ fa[u][i-1] ][i-1];
            max_e[u][i] = max(max_e[u][i-1], max_e[ fa[u][i-1] ][i-1]);
        }
    }
    
    int cal(int u, int lca)
    {
        int d = dep[u] - dep[lca];
        int res = 0;
        for(int i = 18; i >= 0; i--)
        {
            if ((1<<i) <= d)
            {
                d -= (1<<i);
                res = max(res, max_e[u][i]);
                u = fa[u][i];
            }
        }
        return res;
    }
    
    //LCA
    int find_q(int x)
    {
        return x == p2[x] ? x : p2[x]=find_q(p2[x]);
    }
    void uone2(int x,int y)
    {
        int t1=find_q(x);
        int t2=find_q(y);
        if(t1!=t2)
        {
            if(rk2[t1]>rk2[t2])p2[t2]=t1;
            else p2[t1]=t2;
            if(rk2[t1]==rk2[t2])rk2[t2]++;
        }
    }
    void LCA(int u)
    {
        vis[u] = 1;
        acr[u] = u;
        for(int p = fst[u]; p != -1; p = e[p].nxt)
        {
            int v = e[p].to;
            if(vis[v]) continue;
            init_fa(v, u, e[p].w);
            LCA(v);
            uone2(u,v);
            acr[find_q(u)] = u;
        }
        for(int p = h[u]; p != -1; p = Q[p].nxt)
        {
            int v = Q[p].to;
            if(vis[v]) ans[Q[p].idx] = acr[find_q(v)];
        }
    }
    
    int main()
    {
    //    freopen("input.txt", "r", stdin);
        scanf("%d%d", &n, &m);
        CLS();
        for (int i = 1; i <= m; i++)
        {
            int a,b,w;
            scanf("%d%d%d",&a,&b,&w);
            p[i].a=s[i].a=a;
            p[i].b=s[i].b=b;
            p[i].w=s[i].w=w;
            add_Q(a,b,i);
            add_Q(b,a,i);
        }
        ll tmp = kruscal();
        LCA(1);
        for (int i = 1; i <= m; i++)
            printf("%I64d
    ", tmp+s[i].w-max(cal(s[i].a, ans[i]), cal(s[i].b, ans[i])));
        return 0;
    }
  • 相关阅读:
    多线程环境下调用 HttpWebRequest 并发连接限制
    i—比 i++ 快?
    文件在不同文件系统间拷贝文件时间改变的问题
    Go websocket 聊天室demo2
    Go websocket 聊天室demo以及k8s 部署
    AcWing 1077. 皇宫看守
    AcWing 1073. 树的中心
    AcWing 1085. 不要62
    AcWing 1081 度的数量
    AcWing 1082. 数字游戏
  • 原文地址:https://www.cnblogs.com/planche/p/8910844.html
Copyright © 2011-2022 走看看