• 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
    ",ans[i]);
    84     }
    85     return 0;
    86 }
  • 相关阅读:
    Ubuntu在下面LAMP(Linux+Apache+MySQL+PHP) 开发环境的搭建
    直接插入排序、折半插入排序、Shell排序、冒泡排序,选择排序
    java插入字符串
    bash,bg,bind,break,builtin,caller,compgen, complete,compopt,continue,declare,dirs,disown,enable,eval,exec,expo
    socket用法
    org.jsoup.select.Selector
    达达技术
    CentOS 6.4 文件夹打开方式
    shell加法
    shell统计
  • 原文地址:https://www.cnblogs.com/Ressed/p/9811075.html
Copyright © 2020-2023  润新知