#include <bits/stdc++.h>
#define int long long
using namespace std;
inline int read() {
int x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-')f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar();
return x * f;
}
struct A {
int x, y, l;
} edge[300010];
struct E {
int to, l;
};
vector<E> tree[100010];
int n, m, father[100010], deep[100010], jump[1000010][20], fir[300010][20], sec[300010][20], sum;
bool used[300010];
int find(int x) {
return x == father[x] ? x : father[x] = find(father[x]);
}
void finddep(int now) {
for (int i = 0; i < tree[now].size(); i++) {
int to = tree[now][i].to;
if (to != jump[now][0]) {
jump[to][0] = now;
deep[to] = deep[now] + 1;
fir[to][0] = tree[now][i].l;
sec[to][0] = LONG_LONG_MIN;
finddep(to);
}
}
}
void init() {
for (int i = 1; i <= 20; i++)
for (int j = 1; j <= n; j++) {
int f = jump[j][i - 1];
jump[j][i] = jump[f][i - 1];
int t[4] = {fir[j][i - 1], sec[j][i - 1], fir[f][i - 1], sec[f][i - 1]};
sort(t, t + 4);
fir[j][i] = t[3];
if (t[3] == t[2])
sec[j][i] = t[1];
else
sec[j][i] = t[2];
}
}
int lca(int x, int y) {
if (deep[x] < deep[y]) swap(x, y);
for (int i = 20; i >= 0; i--)
if (deep[jump[x][i]] >= deep[y])
x = jump[x][i];
if (x == y)
return x;
for (int i = 20; i >= 0; i--) {
if (jump[x][i] != jump[y][i])
x = jump[x][i], y = jump[y][i];
}
return jump[x][0];
}
bool cmp(A a, A b) {
return a.l < b.l;
}
int rmax(int x, int y, int val) {
int ans = 0;
for (int i = 20; i >= 0; i--) {
if (deep[jump[x][i]] >= deep[y]) {
if (fir[x][i] == val)
ans = max(ans, sec[x][i]);
else
ans = max(ans, fir[x][i]);
x = jump[x][i];
}
}
return ans;
}
signed main() {
int ans = LONG_LONG_MAX;
n = read(), m = read();
for (int i = 1; i <= m; i++) {
int x = read(), y = read(), len = read();
if (x == y) {
i--, m--;
continue;
}
edge[i] = {x, y, len};
}
for (int i = 1; i <= n; i++)
father[i] = i;
sort(edge + 1, edge + m + 1, cmp);
for (int i = 1; i <= m; i++) {
int x = find(edge[i].x), y = find(edge[i].y);
if (x != y) {
sum += edge[i].l;
father[x] = y;
used[i] = true;
tree[edge[i].x].push_back({edge[i].y, edge[i].l});
tree[edge[i].y].push_back({edge[i].x, edge[i].l});
}
}
finddep(1);
init();
for (int i = 1; i <= m; i++) {
if (used[i]) continue;
int x = edge[i].x, y = edge[i].y, val = edge[i].l;
int lca1 = lca(x, y), t = max(rmax(x, lca1, val), rmax(y, lca1, val));
ans = min(ans, sum + val - t);
}
cout << ans;
return 0;
}
记录