如题,谢谢了!
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <vector>
#include <queue>
#define EL puts("")
#define MAXN 100000
#define MAXM 300000
#define LOG2N 18
//#define FOPEN 1
//#define DEBUG 1
using namespace std;
int n,m,p_edge[MAXM+100],fa[MAXN+100],dep[MAXN+100],firmax,secmax,maxdepth=-1;
int f1[MAXN+10][LOG2N+1],f2[MAXN+10][LOG2N+1],f3[MAXN+10][LOG2N+1];
long long micnt=0,secnt;
bool e_used[MAXM+100];
vector<int> g[MAXN+100];
struct EdgeNode{
int from, to ,w;
}edge[MAXM+100];
struct GlobalVar{
int re1,re2;
}gv;
bool cmp(int p1,int p2){
return edge[p1].w < edge[p2].w;
}
int getFa(int x){
if (x == fa[x]) return x;
return fa[x] = getFa(fa[x]);
}
void kruskal(){
int cnt = 0;
for (int i=1; i<=m; i++){
int pe = p_edge[i];
int faa = getFa(edge[pe].from),
fab = getFa(edge[pe].to);
if (faa != fab){
micnt += edge[pe].w;
e_used[pe] = true;
cnt ++;
fa[faa] = fab;
}
if (cnt==n-1) break;
}
}
void dfs(int x, int fa, int wei, int d){
f1[x][0] = fa;
f2[x][0] = wei;
f3[x][0] = wei;
dep[x] = d;
int sz = g[x].size();
for (int i=0; i<sz; i++){
int pe = g[x][i];
if (!e_used[pe]) continue;
int son = edge[pe].from;
if (son == x) son = edge[pe].to;
if (son == fa) continue;
dfs(son, x, edge[pe].w, d+1);
}
}
void lca(int a,int b){
if (dep[a] < dep[b]) swap(a,b);
priority_queue<int> q;
for (int i=log2(dep[a]-dep[b]); i>=0; i--){
if ((1<<i) <= dep[a]-dep[b]){
q.push(f2[a][i]);
q.push(f3[a][i]);
a = f1[a][i];
}
}
if (a==b) goto RE;
for (int i=log2(dep[a]); i>=0; i--){
if (f1[a][i] != f1[b][i]){
q.push(f2[a][i]);
q.push(f3[a][i]);
q.push(f2[b][i]);
q.push(f3[b][i]);
a = f1[a][i];
b = f1[b][i];
}
}
q.push(f2[a][0]);
q.push(f3[a][0]);
q.push(f2[b][0]);
q.push(f3[b][0]);
RE:
gv.re1 = q.top();q.pop();
while (!q.empty()){
gv.re2 = q.top();q.pop();
if (gv.re1 != gv.re2) return;
}
}
int main(){
#ifdef FOPEN
freopen("input","r",stdin);
#endif
int x,y,z;
cin>>n>>m;
for (int i=1; i<=m; i++){
scanf("%d%d%d",&x,&y,&z);
g[x].push_back(i);
g[y].push_back(i);
edge[i].from = x;
edge[i].to = y;
edge[i].w = z;
p_edge[i] = i;
}
sort(p_edge+1,p_edge+1+m,cmp);
memset(e_used, false, sizeof(e_used));
for (int i=1; i<=n; i++) fa[i] = i;
kruskal();
dfs(1, 1, -1, 0);
#ifdef DEBUG
printf("mincnt = %lld\n", micnt);
#endif
for (int i=1; i<=LOG2N; i++){
for (int u=1; u<=n; u++){
priority_queue<int> q;
f1[u][i] = f1[ f1[u][i-1] ][i-1];
q.push(f2[u][i-1]);
q.push(f3[u][i-1]);
q.push(f2[ f1[u][i-1] ][i-1]);
q.push(f3[ f1[u][i-1] ][i-1]);
f2[u][i] = q.top();q.pop();
while (!q.empty()){
f3[u][i] = q.top();q.pop();
if (f3[u][i] != f2[u][i]) break;
}
}
}
int minn = 1000000000;
for (int i=1; i<=m; i++){
if (!e_used[i]){
lca(edge[i].from, edge[i].to);
#ifdef DEBUG
printf("from = %d, to = %d, gv.re1 = %d, gv.re2 = %d\n",edge[i].from, edge[i].to,gv.re1,gv.re2);
#endif
int t;
if (gv.re1 == edge[i].w) t = gv.re2;
else t = gv.re1;
if (t == edge[i].w) continue;
if (t == edge[i].w-1){
printf("%lld",micnt+1);
return 0;
}
if (edge[i].w - t < minn) minn = edge[i].w -t;
}
}
printf("%lld",micnt + minn);
#ifdef FOPEN
fclose(stdin);
#endif
}