采用维护最大值和次大值的方法。然后死活调不对了,求大佬指出错误,谢谢。
#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define CHECK cout<<"WALKED"<<endl;
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<<3)+(x<<1)+ch-'0',ch=getchar();return x*f;}
ll binpow(ll a, ll b, ll mod){ll res = 1; while (b > 0){if (b & 1) res = res * a % mod;a = a * a % mod; b >>= 1; } return res;}
using namespace std;
const int N = 1e5 + 10;
int n, m;
int fa[N];
int trfa[N][22], dep[N];
ll st_max1[N][22], st_max2[N][22];
void init() {for (int i = 1; i <= n; i++) fa[i] = i;}
int find(int x) {if (x == fa[x]) return fa[x]; return fa[x] = find(fa[x]);}
inline void merge(int x, int y) {x = find(x); y = find(y); if (x != y) fa[x] = y;}
struct edges {int u, v, w;}; vector<edges> tr[N], info;
ll W;
bool p[3 * N];
bool cmp(edges a, edges b) {return a.w < b.w;}
void kruskal()
{
int cnt = n;
for (int i = 0; i < (int)info.size(); i++) {
edges k = info[i];
if (cnt == 0) break;
if (find(k.u) != find(k.v)) {
merge(k.v, k.u);
W += k.w;
tr[k.u].push_back({k.u, k.v, k.w});
tr[k.v].push_back({k.v, k.u, k.w});
p[i] = true;
cnt--;
}
}
}
void dfs(int u, int f)
{
trfa[u][0] = f;
dep[u] = dep[f] + 1;
for (int i = 1; i <= 20; i++) {
trfa[u][i] = trfa[trfa[u][i - 1]][i - 1];
st_max1[u][i] = max(st_max1[u][i - 1], st_max1[trfa[u][i - 1]][i - 1]);
st_max2[u][i] = max(st_max2[u][i - 1], st_max2[trfa[u][i - 1]][i - 1]);
if (st_max1[u][i - 1] > st_max1[trfa[u][i - 1]][i - 1])
st_max2[u][i] = max (st_max2[u][i], st_max1[trfa[u][i - 1]][i - 1]);
else if (st_max1[u][i - 1] < st_max1[trfa[u][i - 1]][i - 1])
st_max2[u][i] = max (st_max2[u][i], st_max1[u][i - 1]);
// if (st_max1[u][i] < st_max1[u][i - 1]) {
// st_max2[u][i] = st_max1[u][i];
// st_max1[u][i] = st_max1[u][i - 1];
// }
// if (st_max1[u][i] < st_max1[trfa[u][i - 1]][i - 1]) {
// st_max2[u][i] = st_max1[u][i];
// st_max1[u][i] = st_max1[trfa[u][i - 1]][i - 1];
// }
}
for (edges k : tr[u]) {
if (k.v == f) continue;
st_max1[k.v][0] = k.w;
st_max2[k.v][0] = INT_MIN; //
dfs(k.v, u);
}
}
ll query_1(int u, int v)
{
if (dep[u] < dep[v])
swap(u, v);
ll ret = INT_MIN, res = dep[u] - dep[v];
for (int i = 20; i >= 0; i--)
{
if ((res >> i) & 1)
{
ret = max(ret, st_max1[u][i]);
u = trfa[u][i];
}
}
if (u == v)
return ret;
for (int i = 20; i >= 0; i--)
{
if (trfa[u][i] != trfa[v][i])
{
ret = max(ret, max(st_max1[u][i], st_max1[v][i]));
u = trfa[u][i];
v = trfa[v][i];
}
}
return max(ret, max(st_max1[u][0], st_max1[v][0]));
}
ll query_2(int u, int v)
{
if (dep[u] < dep[v]) swap(u, v);
ll ret = INT_MIN;
int res = dep[u] - dep[v];
for (int i = 20; i >= 0; i--) {
if ((res >> i) & 1) {
ret = max(ret, st_max2[u][i]);
u = trfa[u][i];
}
}
if (u == v) return ret;
for (int i = 20; i >= 0; i--) {
if (trfa[u][i] != trfa[v][i]) {
ret = max(ret, max(st_max2[u][i], st_max2[v][i]));
u = trfa[u][i];
v = trfa[v][i];
}
}
return max(ret, max(st_max2[u][0], st_max2[v][0]));
}
int main()
{
scanf("%d%d", &n, &m); init();
for (int i = 1, u, v, w; i <= m; i++) {
scanf("%d%d%d", &u, &v, &w);
info.push_back({u, v, w});
}
sort(info.begin(), info.end(), cmp);
kruskal();
for (int i = 1; i <= n; i++)
if (find(i) == i)
dfs(i, 0);
// cout << query_2(5, 3) << endl;
ll ans = INT_MAX;
for (int i = 0; i < (int)info.size(); i++) {
edges k = info[i];
if (p[i]) continue;
ll res = query_1(k.u, k.v);
if (res == k.w) {cout<<1<<endl;
res = query_2(k.u, k.v);}
ans = min(ans, W - k.w + res);
}
printf("%lld\n", ans);
return 0;
}