自认为码风还算良好,望大佬指教
我的提交记录
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 4e5 + 5;
int n, m, cnt, head[N], fa[N], dep[N], up[N][28], fd[N][28], sd[N][28], vis[N];
ll sum, ans;
struct EDGE{ int u, v, w; }edg[N];
struct node{ int to, nxt, dis; }e[N];
void addedge(int f, int g, int w){
e[++cnt] = node{ g, head[f], w };
head[f] = cnt;
}
bool cmp(EDGE x, EDGE y){ return x.w < y.w; }
int find_(int x){
if(fa[x] == x) return x;
else return fa[x] = find_(fa[x]);
}
void kruskal(){
int tot = 0;
for(int i = 0; i <= n; i++) fa[i] = i;
sort(edg+1, edg+m+1, cmp);
for(int i = 1; i <= m; i++){
if(find_(edg[i].u) != find_(edg[i].v)){
int x = find_(edg[i].u), y = find_(edg[i].v);
if(x != y) fa[x] = y;
sum += edg[i].w;
vis[i] = 1;
++tot;
addedge(edg[i].u, edg[i].v, edg[i].w);
addedge(edg[i].v, edg[i].u, edg[i].w);
}
if(tot == n) break;
}
}
void dfs(int x, int father){//LCA初始化
for(int i = head[x]; i; i = e[i].nxt){
int y = e[i].to, w = e[i].dis;
if(y == father) continue;
dep[y] = dep[x] + 1;
up[y][0] = x;
fd[y][0] = w;
dfs(y, x);
}
}
int lca(int x, int y){
if(dep[x] < dep[y]) swap(x, y);
for(int i = 20; i >= 0; i--)
if(dep[up[x][i]] >= dep[y]) x = up[x][i];
if(x == y) return x;
for(int i = 20; i >= 0; i--)
if(up[x][i] != up[y][i]) x = up[x][i], y = up[y][i];
return up[x][0];
}
int getmax(int x, int y, int force){//force为要加的边权
int maxn = 0;
for(int i = 20; i >= 0; i--){
if(dep[up[x][i]] >= dep[y]){
if(force != fd[x][i]) maxn = max(maxn, fd[x][i]);//删的边不为要加的边
else maxn = max(maxn, sd[x][i]);
x = up[x][i];
}
}
return maxn;
}
int main(){
scanf("%d%d", &n, &m);
for(int i = 1; i <= m; i++)
scanf("%d%d%d", &edg[i].u, &edg[i].v, &edg[i].w);
kruskal();
dfs(1, 0);
for(int j = 1; j <= 20; j++){
for(int i = 1; i <= n; i++){
up[i][j] = up[up[i][j-1]][j-1];
if(fd[i][j-1] > fd[up[i][j-1]][j-1]){
fd[i][j] = fd[i][j-1];
sd[i][j] = max(sd[i][j-1], fd[up[i][j-1]][j-1]);
}else if(fd[i][j-1] < fd[up[i][j-1]][j-1]){
fd[i][j] = fd[up[i][j-1]][j-1];
sd[i][j] = max(sd[up[i][j-1]][j-1], fd[i][j-1]);
}else{
fd[i][j] = fd[i][j-1];
sd[i][j] = max(sd[i][j-1], sd[up[i][j-1]][j-1]);
}
}
}
for(int i = 1; i <= m; i++){
if(vis[i]) continue;
int u = edg[i].u, v = edg[i].v, w = edg[i].w, x = lca(u, v);
int maxn = max(getmax(u, x, w), getmax(v, x, w));
ans = max(ans, sum - maxn + w);
}
printf("%lld", ans);
return 0;
}