[模板] 最小树形图/朱刘算法
最小树形图
图的 (叶向) 树形图指的是从一个点出发, 能到达其他所有节点, 且基图是一棵树的子图.
求图的最小树形图常用朱刘算法, 时间复杂度 \(O(nm)\).
一个例子:
代码
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];
}
}