cf609E Minimum Spanning Tree For Each Edge (kruskal+倍增Lca)

先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\n",ans[i]);
84     }
85     return 0;
86 }

猜你喜欢

转载自www.cnblogs.com/Ressed/p/9811075.html