1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
| #include <bits/stdc++.h> #define int long long using namespace std; const int MAXN=1e5+2; const int MAXM=3e5+2; const int INF=0x7fffffffffffffff;
struct Tr{ private: struct edge{ int v,w; }; vector<edge> p[MAXN]; int fa[MAXN][31],dep[MAXN],m[MAXN][31],mm[MAXN][31];
public: void add(int u,int v,int w){ p[u].push_back({v,w}); p[v].push_back({u,w}); }
void dfs(int x,int fno){ if(fno)dep[x]=dep[fno]+1,fa[x][0]=fno,mm[x][0]=-INF;
for(int i=1;i<=30;++i){ fa[x][i]=fa[fa[x][i-1]][i-1]; int tmp[4]={m[x][i-1],m[fa[x][i-1]][i-1], mm[x][i-1],mm[fa[x][i-1]][i-1]}; sort(tmp,tmp+4); m[x][i]=tmp[3]; int ptr=2; for(;ptr>=0&&tmp[ptr]==tmp[3];){--ptr;} mm[x][i]=ptr==-1?-INF:tmp[ptr]; }
for(auto& edge:p[x]){ int v=edge.v,w=edge.w; if(v==fno)continue; m[v][0]=w; dfs(v,x); } }
int lca(int x,int y){ if(dep[x]>dep[y])swap(x,y); for(int i=30;i>=0;--i){ if(dep[fa[y][i]]>=dep[x])y=fa[y][i]; } if(x==y)return x; for(int i=30;i>=0;--i){ if(fa[x][i]!=fa[y][i]){ x=fa[x][i],y=fa[y][i]; } } return fa[x][0]; }
int query(int x,int y,int w){ int ret=-INF; for(int i=30;i>=0;--i){ if(dep[fa[x][i]]>=dep[y]){ if(w!=m[x][i]) ret=max(ret,m[x][i]); else ret=max(ret,mm[x][i]); x=fa[x][i]; } } return ret; } };
Tr tr;
struct _edge_{ int u,v,w; bool operator<(const _edge_& other)const{return w<other.w;} };
vector<_edge_> edges; int fa[MAXN],n,m,used[MAXM];
int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);} void unite(int u,int v){int fu=find(u),fv=find(v);if(fu!=fv)fa[fu]=fv;}
int kruskal(){ int ans=0,cnt=0; for(int i=1;i<=n;++i)fa[i]=i; sort(edges.begin(),edges.end()); for(int i=0;i<edges.size();++i){ _edge_ e=edges[i]; int u=e.u,v=e.v,w=e.w; if(find(u)!=find(v)){ unite(u,v); ans+=w,++cnt; used[i]=1; tr.add(u,v,w); } if(cnt==n-1)break; } return ans; }
signed main(){ cin>>n>>m; for(int i=1;i<=m;++i){ int u,v,w;cin>>u>>v>>w; edges.push_back({u,v,w}); } int ans_1=kruskal(),ans_2=INF; tr.dfs(1,0); for(int i=0;i<edges.size();++i){ if(!used[i]){ int u=edges[i].u,v=edges[i].v,w=edges[i].w; int _lca=tr.lca(u,v); int tmp1=tr.query(u,_lca,w); int tmp2=tr.query(v,_lca,w); int _m=max(tmp1,tmp2); if(_m>-INF) ans_2=min(ans_2,ans_1-_m+w); } } if(ans_2!=INF)cout<<ans_2<<endl; else cout<<-1<<endl; }
|