1 /*
2 Source :CF 609E
3 Problem :给定n个顶点,m条边的图,对于一条边,求包含这条边的最小生成树
4 Solution :先求出MST,然后对于一条给定的边,对应的最小生成树为MST中去掉u,v路径上的最大的边,然后加上当前的边
5 对于后面的问题,求解u,v路径上的最大边,可用树上的倍增法解决。
6 Date :2018-08-16-20.46
7 */
8
9 #include <bits/stdc++.h>
10 using namespace std;
11
12 typedef long long LL;
13 const int MAXN = 100005;
14 const LL MOD7 = 1e9+7;
15
16 struct E
17 {
18 int u,v,c;
19 int idx;
20 }e[2*MAXN];
21 LL Ans[2*MAXN];
22
23 int cmp(E a,E b)
24 {
25 return a.c<b.c;
26 }
27
28 struct Edge
29 {
30 int u,v,c;
31 int next;
32 }edge[4*MAXN];
33 int head[2*MAXN];
34 int cnt;
35
36
37 int dep[2*MAXN];
38 int f[2*MAXN][30];
39 int dp[2*MAXN][30];
40 int n,m;
41
42
43 void init()
44 {
45 memset(head,-1,sizeof(head));
46 cnt=0;
47 }
48
49 void addEdge(int u,int v,int c)
50 {
51 edge[cnt].u=u;edge[cnt].v=v;edge[cnt].c=c;edge[cnt].next=head[u];head[u]=cnt++;
52 }
53
54 void dfs(int u,int pre,int c)
55 {
56 f[u][0]=pre;
57 dp[u][0]=c;
58 for (int i=head[u];i!=-1;i=edge[i].next)
59 {
60 int v=edge[i].v;
61 if (v==pre) continue;
62 dep[v]=dep[u]+1;
63 dfs(v,u,edge[i].c);
64 }
65 }
66
67 void BZ()
68 {
69 for (int j=1;j<30;++j)
70 {
71 for (int i=1;i<=n;++i)
72 {
73 if (f[i][j-1])
74 {
75 f[i][j]=f[f[i][j-1]][j-1];
76 dp[i][j] = max(dp[i][j-1], dp[f[i][j-1]][j-1]);
77 }
78 }
79 }
80 }
81
82 int query(int u,int v)
83 {
84 if (dep[u]<dep[v]) swap(u,v);
85 int ans=0;
86 int delta=dep[u]-dep[v];
87 for (int i=0;i<30;++i)
88 {
89 if (delta&(1<<i))
90 {
91 ans=max(ans,dp[u][i]);
92 u=f[u][i];
93 }
94 }
95 if (u==v) return ans;
96 for (int i=29;i>=0;--i)
97 {
98 if (f[u][i]!=f[v][i])
99 {
100 ans=max(ans, dp[u][i]);
101 ans=max(ans, dp[v][i]);
102 u=f[u][i];
103 v=f[v][i];
104 }
105 }
106 ans=max(ans, dp[u][0]);
107 ans=max(ans, dp[v][0]);
108 return ans;
109 }
110
111 struct Union_set
112 {
113 int f[2*MAXN];
114 void init(int n)
115 {
116 for (int i=1;i<=n;++i) f[i]=i;
117 }
118 int find(int x)
119 {
120 if (x==f[x]) return x;
121 return f[x]=find(f[x]);
122 }
123 bool Union(int x,int y)
124 {
125 int fx=find(x);
126 int fy=find(y);
127 if (fx==fy) return false;
128 f[fx]=fy;
129 return true;
130 }
131 }union_set;
132
133 int main()
134 {
135 #ifndef ONLINE_JUDGE
136 freopen("test.txt","r",stdin);
137 #endif // ONLINE_JUDGE
138 while (scanf("%d%d",&n,&m)!=-1)
139 {
140 init();
141 int u,v,c;
142 for (int i=1;i<=m;++i)
143 {
144 scanf("%d%d%d",&u,&v,&c);
145 e[i].u=u;e[i].v=v;e[i].c=c;
146 e[i].idx=i;
147 }
148 sort(e+1,e+1+m,cmp);
149 union_set.init(n);
150 LL ans=0;
151 for (int i=1;i<=m;++i)
152 {
153 u=e[i].u;
154 v=e[i].v;
155 if (union_set.Union(u,v))
156 {
157 ans+=e[i].c;
158 addEdge(u,v,e[i].c);
159 addEdge(v,u,e[i].c);
160 }
161 }
162 // printf("MST ans=%I64d\n",ans);
163 dep[1]=1;
164 dfs(1,0,0);
165 BZ();
166 for (int i=1;i<=m;++i)
167 {
168 u=e[i].u;
169 v=e[i].v;
170 c=e[i].c;
171 Ans[e[i].idx]=ans+c-query(u,v);
172 // printf("query(%d,%d) = %d\n",u,v,query(u,v));
173 }
174 for (int i=1;i<=m;++i) printf("%I64d\n",Ans[i]);
175 }
176 return 0;
177 }