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;
    }
  • 相关阅读:
    【Python入门 】—— 关于Numpy的使用
    CSP 201512 | 201604考试题目
    【Python入门】 —— 用pycharm写7道简单的PTA题目吧!
    【Python入门】 —— 用pycharm写两道超简单的PTA题目~
    Crypto.AES 报错 | TypeError: Object type <class 'str'> cannot be passed to C code
    windows安装Pytorch报错:from torch._C import * ImportError: DLL load failed: 找不到指定的模块”解决方案
    Python中的self通俗理解(自己理解的,自我感觉比官网解释要容易懂)
    python获取token数据
    python根据对象的实例获取对象的属性值
    oracle查询某个字段不为空的sql语句
  • 原文地址:https://www.cnblogs.com/planche/p/8910844.html
Copyright © 2011-2022 走看看