题目链接:http://codeforces.com/contest/609/problem/E

题意:给一个无向图,n个点,m条边,对任意边edge[i],求出包含有边edge[i]的最小生成树。

解法:考虑MST的性质,对任意两点u,v一定有且只有一条路径,当边[u,v]不是MST边的时候,加入边[u,v]便

会形成环,于是在u到v的路径上找一条权值最大的边删去再加入边[u,v],之前环上的任意两点仍然连通。

u到v路径的最大值用LCA来维护。

//CF 609E

#include <bits/stdc++.h>
using namespace std;

const int maxn = 2e5+5;
struct edge1{
    int u, v, w, id;
}E1[maxn*2];
struct edge2{
    int v, w, nxt;
}E2[maxn*2];
int head[maxn], edgecnt, n, m;
void init(){
    memset(head, -1, sizeof(head));
    edgecnt=0;
}
void add(int u, int v, int w){
    E2[edgecnt].v = v, E2[edgecnt].w = w,E2[edgecnt].nxt = head[u], head[u] = edgecnt++;
}
int pa[maxn];
int find_set(int x){
    if(x == pa[x]) return x;
    else return pa[x] = find_set(pa[x]);
}
bool cmp(const edge1 &a, const edge1 &b){
    return a.w < b.w;
}
long long build(){
    sort(E1+1, E1+m+1, cmp);
    for(int i=1;i<=n;i++) pa[i]=i;
    int cnt=0;
    long long ans=0;
    for(int i=1; i<=m; i++){
        int x=E1[i].u, y=E1[i].v;
        int fx = find_set(x), fy = find_set(y);
        if(fx==fy) continue;
        add(E1[i].u, E1[i].v, E1[i].w);
        add(E1[i].v, E1[i].u, E1[i].w);
        pa[fx]=fy;
        ans+=E1[i].w;
        cnt++;
        if(cnt==n-1) break;
    }
    return ans;
}


int dep[maxn],p[20][maxn],maxv[20][maxn];
void dfs(int u,int f,int d,int w)
{
    dep[u]=d;
    p[0][u]=f,maxv[0][u]=w;
    for(int i=head[u]; ~i; i=E2[i].nxt)
    {
        int v=E2[i].v;
        if(v==f) continue;
        dfs(v,u,d+1,E2[i].w);
    }
}
void build2()
{
    dfs(1,-1,0,0);
    for(int i=0; i+1<18; i++)
    {
        for(int v=1; v<=n; v++)
        {
            if(p[i][v]<0) p[i+1][v]=-1;
            else p[i+1][v]=p[i][p[i][v]];
            maxv[i+1][v] = max(maxv[i][v],maxv[i][p[i][v]]);
        }
    }
}
int lca(int u,int v)
{
    if(dep[u]>dep[v]) swap(u,v);
    for(int i=0; i<18; i++) if(dep[u]-dep[v]>>i&1) v=p[i][v];
    if(u==v) return u;
    for(int i=17; ~i; i--)
        if(p[i][u]!=p[i][v])
            u=p[i][u],v=p[i][v];
    return p[0][u];
}
int get(int u,int to)
{
    int ret=0;
    for(int i=0; i<18; i++)
        if(dep[u]-dep[to]>>i&1) ret=max(ret,maxv[i][u]),u=p[i][u];
    return ret;
}

long long ans[maxn];

int main()
{
    scanf("%d%d", &n, &m);
    init();
    for(int i=1; i<=m; i++){
        scanf("%d%d%d", &E1[i].u, &E1[i].v, &E1[i].w);
        E1[i].id = i;
    }
    long long mst = build();
    build2();
    for(int i=1; i<=m; i++){
        int _lca = lca(E1[i].u, E1[i].v);
        int xx = max(get(E1[i].u, _lca), get(E1[i].v, _lca));
        ans[E1[i].id] = mst-xx+E1[i].w;
    }
    for(int i=1; i<=m; i++){
        printf("%lld\n", ans[i]);
    }
    return 0;
}