#include<cstdio> #include<cstdlib> #include<algorithm> #define MAXINT 2147483647/2 using namespace std; int a,b,w,n,m,t,tot,ntot=MAXINT; int e[5001][5001],flag[5001],pre[5000],dis[5001]; int maxd[5000][5000]; inline int Prim(int vi) { for (int j=1;j<=n;j++) if (e[vi][j]!=0) dis[j]=e[vi][j],pre[j]=vi; else dis[j]=MAXINT; flag[vi]=1; dis[vi]=0; for (int i=1;i<n;i++) { int min=MAXINT,mink; for (int j=1;j<=n;j++) if (!flag[j] && dis[j]<min) min=dis[j],mink=j; for (int j=1;j<=n;j++) if (flag[j]) maxd[j][mink]=maxd[mink][j]=max(min,maxd[pre[mink]][j]); flag[mink]=1; for (int j=1;j<=n;j++) if (!flag[j] && e[mink][j]!=0 && e[mink][j]<dis[j]) dis[j]=e[mink][j],pre[j]=mink; } for (int j=1;j<=n;j++) tot+=dis[j]; } int main() { scanf("%d%d",&n,&m); for (int i=1;i<=m;i++) scanf("%d%d%d",&a,&b,&w),e[a][b]=w,e[b][a]=w; Prim(1); printf("%d\n",tot); for (int i=1;i<=n;i++) for (int j=i+1;j<=n;j++) if (e[i][j]!=0 && i!=pre[j] && j!=pre[i]) if (tot-maxd[i][j]+e[i][j]<ntot) ntot=tot-maxd[i][j]+e[i][j]; printf("%d\n",ntot); return 0; } /* 9 15 1 2 10 2 3 18 3 4 22 4 5 20 5 6 26 6 1 11 2 7 16 6 7 17 3 9 8 9 4 21 2 9 12 7 4 24 8 4 16 8 5 7 7 8 19 99 101 */
BZOJ 1977
#include<cstdio> #include<cstdlib> #include<algorithm> #include<iostream> #define V G[p].v #define oo 1<<30 using namespace std; typedef long long ll; inline char nc() { static char buf[100000],*p1=buf,*p2=buf; if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; } return *p1++; } inline void read(int &x) { char c=nc(),b=1; for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1; for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b; } struct edge{ int u,v,w; int next; }; edge G[200005]; int head[100005],num=1; inline void add(int u,int v,int w,int p) { G[p].u=u; G[p].v=v; G[p].w=w; G[p].next=head[u]; head[u]=p; } inline void link(int u,int v,int w) { add(u,v,w,++num); add(v,u,w,++num); } struct Edge{ int u,v,w; int flag; bool operator < (const Edge &B) const{ return w<B.w; } }E[300005]; int n,m; ll tot,ans; int fat[100005]; inline int getfat(int u) { if (u==fat[u]) return u; return fat[u]=getfat(fat[u]); } inline void Kru() { int fx,fy; for (int i=1;i<=n;i++) fat[i]=i; for (int i=1;i<=m;i++) { fx=getfat(E[i].u),fy=getfat(E[i].v); if (fx!=fy) { E[i].flag=1; fat[fx]=fy; link(E[i].u,E[i].v,E[i].w); tot+=E[i].w; } } } struct data{ int a,b; data(int _a=-oo,int _b=-oo):a(_a),b(_b) { } }; data operator + (data A,data B) { data ret; if (A.a>B.a) ret.a=A.a,ret.b=max(A.b,B.a); else ret.a=B.a,ret.b=max(A.a,B.b); return ret; } int depth[100005],parent[100005][20]; data mum[100005][20]; inline void dfs(int u,int fa) { parent[u][0]=fa; depth[u]=depth[fa]+1; for (int p=head[u];p;p=G[p].next) if (V!=fa) { dfs(V,u); mum[V][0]=data(G[p].w,-oo); } } inline void Pre() { for (int k=1;k<=18;k++) for (int i=1;i<=n;i++) { parent[i][k]=parent[parent[i][k-1]][k-1]; mum[i][k]=mum[i][k-1]+mum[parent[i][k-1]][k-1]; } } inline int LCA(int u,int v) { if (depth[u]<depth[v]) swap(u,v); for (int k=18;k>=0;k--) if (((depth[u]-depth[v])>>k)&1) u=parent[u][k]; if (u==v) return u; for (int k=18;k>=0;k--) if (parent[u][k]!=parent[v][k]) u=parent[u][k],v=parent[v][k]; return parent[u][0]; } inline data calc(int u,int v) { int lca=LCA(u,v),d; data ret; d=depth[u]-depth[lca]; for (int k=0;k<=18;k++) if ((d>>k)&1) ret=ret+mum[u][k],u=parent[u][k]; d=depth[v]-depth[lca]; for (int k=0;k<=18;k++) if ((d>>k)&1) ret=ret+mum[v][k],v=parent[v][k]; return ret; } int main() { data ret; freopen("t.in","r",stdin); freopen("t.out","w",stdout); read(n); read(m); for (int i=1;i<=m;i++) read(E[i].u),read(E[i].v),read(E[i].w); sort(E+1,E+m+1); Kru(); mum[1][0]=data(-oo,-oo); dfs(1,0); Pre(); ans=1LL<<60; for (int i=1;i<=m;i++) if (!E[i].flag) { ret=calc(E[i].u,E[i].v); if (ret.a==E[i].w && ret.b!=1<<30) ans=min(ans,tot-ret.b+E[i].w); else if (ret.a!=1<<30) ans=min(ans,tot-ret.a+E[i].w); } cout<<ans<<endl; return 0; }