点击打开链接
先求最小生成树的边 这些边的对应值就是生成树的权值 再用这些边建图 对所有非生成树上的边的两点 去掉两者路径上的最长边 然后换为当前边的权值 这个过程求个lca即可
这应该是贪心 最小生成树已经是最优解(克鲁斯卡尔方法中 就是从小边找起 感觉也有贪心的意思) 每换下任何一条边都会增加权重(可能不变) 既然非要换至少一条边 那就只换一条就够了
using namespace std;
struct node1
{
    int id;
    int u;
    int v;
    ll w;
    ll ans;
};
struct node2
{
    int v;
    ll w;
    int next;
};
node1 pre[200010];
node2 edge[400010];
ll maxx[200010][20];
int dp[200010][20];
int first[200010],f[200010],book[200010],deep[200010];
int n,m,num;
bool cmpI(node1 n1,node1 n2)
{
    return n1.w<n2.w;
}
bool cmpII(node1 n1,node1 n2)
{
    return n1.id<n2.id;
}
void addedge(int u,int v,ll w)
{
    edge[num].v=v;
    edge[num].w=w;
    edge[num].next=first[u];
    first[u]=num++;
    return;
}
int getf(int p)
{
    if(f[p]==p) return p;
    else
    {
        f[p]=getf(f[p]);
        return f[p];
    }
}
bool unite(int u,int v)
{
    int fu,fv;
    fu=getf(u);
    fv=getf(v);
    if(fu!=fv)
    {
        f[fv]=fu;
        return true;
    }
    else return false;
}
void dfs(int cur,int pre)
{
    ll w;
    int i,v;
    for(i=first[cur];i!=-1;i=edge[i].next)
    {
        v=edge[i].v,w=edge[i].w;
        if(v!=pre)
        {
            dp[v][0]=cur;
            maxx[v][0]=w;
            deep[v]=deep[cur]+1;
            dfs(v,cur);
        }
    }
    return;
}
void solve()
{
    int i,j;
    memset(dp,0,sizeof(dp));
    memset(maxx,0,sizeof(maxx));
    memset(deep,0,sizeof(deep));
    dp[1][0]=1;
    deep[1]=1;
    dfs(1,-1);
    for(j=1;(1<<j)<=n;j++)
    {
        for(i=1;i<=n;i++)
        {
            dp[i][j]=dp[dp[i][j-1]][j-1];
            maxx[i][j]=max(maxx[i][j-1],maxx[dp[i][j-1]][j-1]);
        }
    }
    return;
}
int getlca(int u,int v)
{
    int i;
    if(deep[u]<deep[v]) swap(u,v);
    for(i=log2(n);i>=0;i--)
    {
        if(deep[dp[u][i]]>=deep[v])
        {
            u=dp[u][i];
        }
    }
    if(u==v) return u;
    for(i=log2(n);i>=0;i--)
    {
        if(dp[u][i]!=dp[v][i])
        {
            u=dp[u][i];
            v=dp[v][i];
        }
    }
    return dp[u][0];
}
ll getmax(int p,int lca)
{
    ll res;
    int i;
    res=0;
    for(i=log2(n);i>=0;i--)
    {
        if(deep[dp[p][i]]>=deep[lca])
        {
            res=max(res,maxx[p][i]);
            p=dp[p][i];
        }
    }
    return res;
}
int main()
{
    ll sum;
    int i,cnt,lca;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        for(i=1;i<=m;i++)
        {
            pre[i].id=i;
            scanf("%d%d%lld",&pre[i].u,&pre[i].v,&pre[i].w);
        }
        for(i=1;i<=n;i++)
        {
            f[i]=i;
        }
        memset(book,0,sizeof(book));
        sort(pre+1,pre+m+1,cmpI);
        cnt=0,sum=0;
        for(i=1;i<=m;i++)
        {
            if(unite(pre[i].u,pre[i].v))
            {
                book[i]=1;
                cnt++,sum+=pre[i].w;
            }
            if(cnt==n-1) break;
        }
        memset(first,-1,sizeof(first));
        num=0;
        for(i=1;i<=m;i++)
        {
            if(book[i])
            {
                addedge(pre[i].u,pre[i].v,pre[i].w);
                addedge(pre[i].v,pre[i].u,pre[i].w);
                pre[i].ans=sum;
            }
        }
        solve();
        for(i=1;i<=m;i++)
        {
            if(!book[i])
            {
                lca=getlca(pre[i].u,pre[i].v);
                int res=max(getmax(pre[i].v,lca),getmax(pre[i].u,lca));
                pre[i].ans=sum-res+pre[i].w;
            }
        }
        sort(pre+1,pre+m+1,cmpII);
        for(i=1;i<=m;i++)
        {
            printf("%lld\n",pre[i].ans);
        }
    }
    return 0;
}
                










