先kruskal求出一个最小生成树,然后对于每条非树边(a,b),从树上找a到b路径上最大的边,来把它替换掉,就是包含这条边的最小生成树
1 #include<bits/stdc++.h> 2 #define pa pair<int,int> 3 #define CLR(a,x) memset(a,x,sizeof(a)) 4 using namespace std; 5 typedef long long ll; 6 const int maxn=2e5+10; 7 8 inline ll rd(){ 9 ll x=0;char c=getchar();int neg=1; 10 while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();} 11 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); 12 return x*neg; 13 } 14 15 struct Edge{ 16 int a,b,l,ne; 17 }eg[maxn*2],eg0[maxn]; 18 int egh[maxn],ect; 19 int N,M; 20 int fa[maxn],f[maxn][20],ma[maxn][20],dep[maxn]; 21 ll ans[maxn]; 22 23 inline void adeg(int a,int b,int c){ 24 eg[++ect].b=b;eg[ect].l=c;eg[ect].ne=egh[a];egh[a]=ect; 25 } 26 27 inline bool cmp(Edge a,Edge b){return a.l<b.l;} 28 int getf(int x){return x==fa[x]?x:fa[x]=getf(fa[x]);} 29 30 void dfs(int x){ 31 for(int i=0;f[x][i]&&f[f[x][i]][i];i++){ 32 f[x][i+1]=f[f[x][i]][i]; 33 ma[x][i+1]=max(ma[x][i],ma[f[x][i]][i]); 34 } 35 for(int i=egh[x];i;i=eg[i].ne){ 36 int b=eg[i].b; 37 if(b==f[x][0]) continue; 38 dep[b]=dep[x]+1; 39 f[b][0]=x;ma[b][0]=eg[i].l; 40 dfs(b); 41 } 42 } 43 44 ll get(int x,int y){ 45 int re=0; 46 if(dep[x]<dep[y]) swap(x,y); 47 for(int i=log2(dep[x]-dep[y]);i>=0&&dep[x]!=dep[y];i--){ 48 if(dep[f[x][i]]>=dep[y]) 49 re=max(re,ma[x][i]),x=f[x][i]; 50 } 51 if(x==y) return re; 52 for(int i=log2(dep[x]);i>=0;i--){ 53 if(f[x][i]!=f[y][i]) 54 re=max(re,max(ma[y][i],ma[x][i])),x=f[x][i],y=f[y][i]; 55 } 56 return max(re,max(ma[y][0],ma[x][0])); 57 } 58 59 int main(){ 60 //freopen("","r",stdin); 61 int i,j,k; 62 N=rd(),M=rd(); 63 for(i=1;i<=M;i++){ 64 eg0[i].a=rd(),eg0[i].b=rd(),eg0[i].l=rd(); 65 eg0[i].ne=i; 66 }sort(eg0+1,eg0+M+1,cmp); 67 ll dis=0; 68 for(i=1;i<=N;i++) fa[i]=i; 69 for(i=1,j=0;i<=M&&j<N-1;i++){ 70 int aa=getf(eg0[i].a),bb=getf(eg0[i].b); 71 if(aa!=bb){ 72 adeg(eg0[i].a,eg0[i].b,eg0[i].l); 73 adeg(eg0[i].b,eg0[i].a,eg0[i].l); 74 dis+=eg0[i].l; 75 fa[aa]=bb;j++; 76 } 77 } 78 dep[1]=1;dfs(1); 79 for(i=1;i<=M;i++){ 80 ans[eg0[i].ne]=dis+eg0[i].l-get(eg0[i].a,eg0[i].b); 81 } 82 for(i=1;i<=M;i++){ 83 printf("%I64d ",ans[i]); 84 } 85 return 0; 86 }