[模板] 最小树形图

最小树形图

图的 (叶向) 树形图指的是从一个点出发, 能到达其他所有节点, 且基图是一棵树的子图.

求图的最小树形图常用朱刘算法, 时间复杂度 \(O(nm)\).

一个例子:

1326473-20190624211919813-1234304538.png

代码

const int nsz=105,msz=1e4+50,ninf=1e9;

struct te{int f,t,v;}e0[msz];
int np,ne,rt;
int in[nsz],pre[nsz],id[nsz],vi[nsz];
//叶向树形图 
ll zhu_liu(){
    ll res=0;
    while(1){
        int cnt=0;
        rep(i,1,np)in[i]=ninf,pre[i]=id[i]=vi[i]=0;
        rep(i,1,ne){
            int f=e0[i].f,t=e0[i].t,v=e0[i].v;
            if(f!=t&&in[t]>v)in[t]=v,pre[t]=f;
        }
        in[rt]=0;
        rep(i,1,np){
            if(in[i]==ninf)return -1;
            res+=in[i];
            int u;
            for(u=i;u!=rt&&id[u]==0&&vi[u]!=i;u=pre[u])vi[u]=i;
            if(vi[u]==i){
                id[u]=++cnt;
                for(int v=pre[u];v!=u;v=pre[v])
                id[v]=cnt;
            }
        }
        if(cnt==0)return res;
        rep(i,1,np)if(id[i]==0)id[i]=++cnt;
        rep(i,1,ne){
            te &e=e0[i];
            int tmp=in[e.t];
            e.f=id[e.f],e.t=id[e.t];
            if(e.f!=e.t)e.v-=tmp;
        }
        np=cnt;
        rt=id[rt];
    }
}

转载于:https://www.cnblogs.com/ubospica/p/11079560.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值