[summary] Zhu Liu algorithm of minimum tree graph

Preface I found that I didn't write a blog when I was reviewing... To fill in one.. Minimum Arborescence It is the minimum spanning tree of digr...

Preface

I found that I didn't write a blog when I was reviewing...

To fill in one..

Minimum Arborescence

It is the minimum spanning tree of digraph, which can reach all nodes from the root, and has the least edge weight.

Zhu Liu algorithm

In a very violent way, each point selects the smallest one among the edges pointing to it (the root node is not selected).

Then add the edge weight of each point.

Then there may be a ring, shrink it to a point, and then change the edge weight


val '- = val indicates that if val' is selected later, val must be disconnected

Keep doing this until you can't find the ring once and then stop.

Complexity O(N * M)O(N*M)O(N * M)

Template problem

BZOJ4349

The first time is the minimum tree chart, and the second time and later attack, just use the minimum one.

#include<cstdio> #include<algorithm> #include<cmath> #include<cstring> #include<vector> #define SF scanf #define PF printf #define INF 0x3FFFFFFF #define MAXN 60 #define MAXM 2600 using namespace std; struct Edge{ int u,v; double val; Edge() {} Edge(int u1,int v1,double val1):u(u1),v(v1),val(val1) {} }edge[MAXM]; int num[MAXN],pre[MAXN],id[MAXN],vis[MAXN]; double minv[MAXN],in[MAXN]; int rt,ncnt; double solve(int n){ double res=0; while(1){ for(int i=1;i<=n;i++) in[i]=INF; for(int i=1;i<=ncnt;i++){ int u=edge[i].u; int v=edge[i].v; double val=edge[i].val; if(in[v]>val){ in[v]=val; pre[v]=u; } } int tot=0; memset(id,0,sizeof id); memset(vis,0,sizeof vis); in[rt]=0; for(int i=1;i<=n;i++){ res+=in[i]; int v=i; while(vis[v]!=i&&id[v]==0&&v!=rt){ vis[v]=i; v=pre[v]; } if(v!=rt&&id[v]==0){ id[v]=++tot; for(int u=pre[v];u!=v;u=pre[u]) id[u]=tot; } } if(tot==0) break; for(int i=1;i<=n;i++) if(id[i]==0) id[i]=++tot; int cnt1=0; for(int i=1;i<=ncnt;i++){ int u=edge[i].u; int v=edge[i].v; double val=edge[i].val; val-=in[v]; if(id[u]!=id[v]) edge[++cnt1]=Edge(id[u],id[v],val); } rt=id[rt]; n=tot; ncnt=cnt1; } return res; } int main(){ int n,u,v,m; double val; SF("%d",&n); n++; rt=n; for(int i=1;i<=n-1;i++){ SF("%lf%d",&val,&num[i]); minv[i]=val; edge[++ncnt]=Edge(rt,i,val); } SF("%d",&m); for(int i=1;i<=m;i++){ SF("%d%d%lf",&u,&v,&val); minv[v]=min(minv[v],val); edge[++ncnt]=Edge(u,v,val); } double res=solve(n); for(int i=1;i<n;i++) res+=(num[i]-1)*minv[i]; PF("%.2lf",res); }

2 December 2019, 01:29 | Views: 2230

Add new comment

For adding a comment, please log in
or create account

0 comments