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 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
| #include<bits/stdc++.h> using namespace std; #define in read() #define ll long long const int inf=0x3f3f3f3f; inline int read(){ int x=0,f=1;char c=getchar(); while(c<'0'||c>'9'){ if(c=='-') f=-1; c=getchar(); } while(c>='0'&&c<='9'){ x=(x<<1)+(x<<3)+c-'0'; c=getchar(); } return x*f; } const int maxn=3e5+10; struct edge{ int u,v,w,nxt; bool vis; }e[maxn<<1]; int cnt=0,h[maxn]; inline void add(int u,int v,int w){ e[++cnt]=(edge){u,v,w,h[u]}; h[u]=cnt;e[cnt].vis=0; } ll vall; int n,m; int dep[maxn],siz[maxn],hson[maxn],fa[maxn],w[maxn],id[maxn]; int dfn[maxn],num[maxn],top[maxn],tot=0; void dfs1(int x,int father){ siz[x]=1; hson[x]=0; for(int i=h[x];i;i=e[i].nxt){ int v=e[i].v; if(v==father) continue; dep[v]=dep[x]+1; fa[v]=x; dfs1(v,x); w[v]=e[i].w; siz[x]+=siz[v]; if(siz[hson[x]]<siz[v]) hson[x]=v; } } void dfs2(int x,int tp){ top[x]=tp; num[x]=++tot; dfn[tot]=x; if(hson[x]) dfs2(hson[x],tp); for(int i=h[x];i;i=e[i].nxt){ int v=e[i].v; if(v!=fa[x]&&hson[x]!=v) dfs2(v,v); } } int fat[maxn]; int find(int x){ if(x!=fat[x]) fat[x]=find(fat[x]); return fat[x]; } bool cmp(edge a,edge b){ return a.w<b.w; } void kruskal(){ sort(e+1,e+1+m,cmp); for(int i=1;i<=n;i++) fat[i]=i; int sum=0,fu,fv,u,v; for(int i=1;i<=m;i++){ u=e[i].u,v=e[i].v; fu=find(u),fv=find(v); if(fu!=fv){ add(u,v,e[i].w);add(v,u,e[i].w); fat[fu]=fv; vall+=e[i].w; ++sum; e[i].vis=1; if(sum==n-1) break; } } } struct tree{ int l,r,max,sec; }t[maxn<<2]; void pushup(int p){ t[p].max=max(t[p<<1].max,t[p<<1|1].max); if(t[p<<1].max==t[p<<1|1].max) t[p].sec=max(t[p<<1].sec,t[p<<1|1].sec); else t[p].sec=min(t[p<<1].max,t[p<<1|1].max); } void build(int l,int r,int p){ t[p].l=l;t[p].r=r; if(l==r){ t[p].max=w[dfn[l]]; return ; } int mid=(l+r)>>1; build(l,mid,p<<1); build(mid+1,r,p<<1|1); pushup(p); } int querymax(int l,int r,int p,int key){ if(t[p].l>r||t[p].r<l) return -inf; if(l<=t[p].l&&t[p].r<=r){ if(key==t[p].max) return t[p].sec; return t[p].max; } int mid=t[p].l+t[p].r>>1; if(r<=mid) return querymax(l,r,p<<1,key); else if(mid<l) return querymax(l,r,p<<1|1,key); else return max(querymax(l,mid,p<<1,key),querymax(mid+1,r,p<<1|1,key)); } int getmax(int x,int y,int key){ int ans=-inf; while(top[x]!=top[y]){ if(dep[top[x]]<dep[top[y]]) swap(x,y); ans=max(ans,querymax(num[top[x]],num[x],1,key)); x=fa[top[x]]; } if(num[x]>num[y]) swap(x,y); ans=max(ans,querymax(num[x]+1,num[y],1,key)); return ans; } int main(){ n=in;m=in; for(int i=1;i<=m;i++){ e[i].u=in; e[i].v=in; e[i].w=in; } cnt=m; kruskal(); dfs1(1,0); dfs2(1,1); build(1,n,1); ll ans=1e18; for(int i=1;i<=m;i++){ if(!e[i].vis) ans=min(ans,vall+e[i].w-getmax(e[i].u,e[i].v,e[i].w)); } printf("%lld\n",ans); return 0; }
|