EZOJ #386 最小生成树

Posted yzxverygood

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了EZOJ #386 最小生成树相关的知识,希望对你有一定的参考价值。

分析

先建出最小生成树

之后每次倍增找环即可

代码

#include<bits/stdc++.h>
using namespace std;
#define int long long
struct node 
    int x,y,z,is,id;
;
node d[400100];
int head[800100],nxt[800100],to[800100],w[800100],cnt,res,dep[400100];
int pr[400100][23],sum[400100][23],n,m,ans[400100],fa[400100],tot;
inline void add(int x,int y,int z)
    nxt[++cnt]=head[x];
    head[x]=cnt;
    to[cnt]=y;
    w[cnt]=z;
    nxt[++cnt]=head[y];
    head[y]=cnt;
    to[cnt]=x;
    w[cnt]=z;

inline void dfs(int x,int fa)
    dep[x]=dep[fa]+1;
    pr[x][0]=fa;
    for(int i=head[x];i;i=nxt[i])
      if(to[i]!=fa)sum[to[i]][0]=w[i],dfs(to[i],x);

inline int lca(int x,int y)
    if(dep[x]<dep[y])swap(x,y);
    int len=dep[x]-dep[y],wh=0;
    for(int i=0;i<=20;i++)
      if((1<<i)&len)wh=max(wh,sum[x][i]),x=pr[x][i];
    if(x==y)return wh;
    for(int i=20;i>=0;i--)
      if(pr[x][i]!=pr[y][i])
          wh=max(wh,max(sum[x][i],sum[y][i]));
          x=pr[x][i];
          y=pr[y][i];
      
    wh=max(wh,max(sum[x][0],sum[y][0]));
    return wh;

inline bool cmp(const node a,const node b)return a.z<b.z;
inline int sf(int x)return fa[x]==x?x:fa[x]=sf(fa[x]);
signed main()
    int i,j,k;
    scanf("%lld%lld",&n,&m);
    for(i=1;i<=m;i++)
      scanf("%lld%lld%lld",&d[i].x,&d[i].y,&d[i].z);
      d[i].id=i;
    
    for(i=1;i<=n;i++)fa[i]=i;
    sort(d+1,d+m+1,cmp);
    for(i=1;i<=m;i++)
      int x=d[i].x,y=d[i].y;
      if(sf(x)==sf(y))continue;
      fa[sf(y)]=sf(x);
      add(x,y,d[i].z);
      res+=d[i].z;
      tot++;
      d[i].is=1;
      if(tot==n-1)break;
    
    dfs(1,0);
    for(i=1;i<=20;i++)
      for(j=1;j<=n;j++)
        pr[j][i]=pr[pr[j][i-1]][i-1],
        sum[j][i]=max(sum[j][i-1],sum[pr[j][i-1]][i-1]);
    for(i=1;i<=m;i++)
      if(d[i].is)ans[d[i].id]=res;
        else ans[d[i].id]=res+d[i].z-lca(d[i].x,d[i].y);
    
    for(i=1;i<=m;i++)printf("%lld\n",ans[i]);
    return 0;

以上是关于EZOJ #386 最小生成树的主要内容,如果未能解决你的问题,请参考以下文章

如何画出最小生成树即最小支撑树?

c语言最小生成树

图——最小生成树

最小生成树 求大神解救

图的最小生成树算法?

[LuoguP4208][JSOI2008]最小生成树计数(最小生成树+矩阵树定理)