What is the minimum tree chart? I believe that if you will come to see this article, presumably should also have some knowledge of the minimum spanning tree, the minimum spanning tree is the least weight of a spanning tree of the non-graph. Our smallest tree diagram is to solve a graph of the minimum weight of a spanning trees, for the degree Niang, the minimum map is defined as: the minimum tree diagram, is to give a weighted graph to assign a special point root, to a root root of the forward spanning Tree T, And the total weight of all sides in T is the smallest. an algorithm for the minimum tree diagram of general solution is the 1965 Zhu Yongzin and Liuzhenhong proposed the complexity of O (VE) algorithm: Zhu, Liu algorithm.
Today we are going to talk about the minimum tree diagram problem.
The complete composition of the Zhu and Liu Algorithms is composed of four major steps:
1. Finding the shortest arc set E
2, the judgment set E there is no direction ring, if there is a turn step 3, otherwise turn 4
3, the contraction point, the forward ring contraction into a point, and the diagram is rebuilt, including the edge weight value of the change and the processing of points, and then go to step 1.
4, expand the contraction point, to obtain the minimum tree shape chart.
Since our ACM is generally in the expedition the minimum tree graph of the weight problem, so generally omit step 4, for its ring weight and in the middle process can be processed. So we're not going to talk about a fourth point here.
We process it in steps,
1, first we first ask for the shortest arc set E, for the current graph if there are n points (a point of contraction of a forward ring counted as a dot), we have to select N-1 point, determine its edge in the shortest side, composed of a set we call the shortest arc set E, if we enumerate to a point, it does not enter the edge, That means there is no minimum tree diagram, so this time the algorithm ends and returns to the main function.
Code implementation:
for (int i=1; i<=n; i++) if (I!=u&&!flag[i])//u as the root node of the graph, the case of flag "I" is 1, which means that the point is inside a certain ring, and he is not the representative point of the forward ring (indent). { W[i][i]=inf, pre[i] = i;//First let the precursor point of the current point be itself. for (int j=1; j<=n; J + +) if (!flag[j] && w[j][i]<w[pre[i]][i])//The precursor of the enumeration I (from J to the point of I), and to find the shortest side, join the set E { Pre[i] = j;//and marks the current point of the precursor as J } if (pre[i]==i) return-1;//If the currently enumerated point I is not in the edge, Then there is no minimum tree graph (because a tree is to be connected to all nodes) }
2. We then judge the edges in the set E to determine if there is a forward ring. Just the code implementation has a precursor node in the storage, so in this section, we directly forward enumeration of the precursor point, if the enumeration of the precursor to the end can be enumerated to the root node, then this part does not have a forward loop, otherwise there is, for each point is a forward enumeration.
int i; for (I=1; i<=n; i++) { if (I!=u&&!flag[i]) { int j=i, cnt=0; while (j!=u && pre[j]!=i && cnt<=n) j=pre[j], ++cnt;//find the precursor node for each node to see if it can become a loop. if (j==u | | cnt>n) continue;//finally can find the starting point (root) or the point has passed more than N, indicating that there is no forward ring break;//there is a forward ring } }
3, if there is a direction ring, we need to indent the ring, since we are enumerated to the node I found that there is a forward ring, we may wish to the inner ring inside the point is shrunk to point I. A new graph is formed after the contraction, and the pattern of changes is as follows:
Translated into language description: If the point u within the ring, if the point K is outside the ring, and from K to u there is an edge map "u" "V" =w, and there is a little I in the ring, so that the map "i" "K" =w2, spicy map "k" "contraction point" =W-W2;
Based on the greedy thought, for the contraction point of the ring I and another point K (also in the ring), for the outside of the ring J, if the map "K" "J" <map "I" "j", spicy map "i" "J" =map "K" "J", because it is a graph, into the edge of the contraction point to The edge of the contraction point is also to be treated as such, for just three steps: contraction point, shrinkage point processing new graph Benquan value, and based on the greedy thought of the final processing point I of the edge-to-edge weight value, the latter two we can be combined into an operation, its separate code implementation:
3, Shrinkage point:
int j=i; memset (Vis, 0, sizeof (VIS)); do { ans + = w[pre[j]][j], j=pre[j], vis[j]=flag[j]=true;//points within the ring, and directly to the weight of the ring to add and record, after the last to find the smallest tree figure, no need to expand the contraction point } while (j!=i); Flag[i] = false; The ring shrinks into point I, the point I still exists
4, the processing shrinkage point formed after the diagram:
for (int k=1; k<=n; ++k) if (Vis[k]) //At the midpoint of the ring, just at the point of contraction, the points in the ring have been marked. { for (int j=1; j<=n; J + +) if (!vis[j]) //points not in the ring { if (W[i][j] > W[k][j]) w[i][j] = W[k][j ]; if (W[j][k]<inf && w[j][k]-w[pre[k]][k] < w[j][i]) w[j][i] = w[j][k]-w[pre[k]][k]; } }
After processing 4, we go back to step 1, continue to find the smallest arc set E, and finally find the smallest arc set e without a ring, for all the edges in set e without arcs (including those that can expand the shrinking point) are the edge sets of the minimum tree diagram we require.
Because we generally seek the ACM is the smallest tree graph weights, so we generally do not need to expand the contraction point, in the processing ring, directly the edge of the value of the record down, when found a non-ring set E, the last side of the weight of the sum can be added, for the last part of the weighting, code implementation:
if (i>n)//This code is immediately after the code 2, if the enumeration of all points I did not find a forward ring, spicy is to find this final set. { for (int i=1; i<=n; i++) if (I!=u &&!flag[i]) ans+=w[pre[i]][i];//Finally, all the edges in this final set of e are added and can be. return ans; }
Complete ink and Liu Algorithm code implementation (no expansion of the contraction point):
void init ()//cannot be less initialized with content {memset (vis, 0, sizeof (VIS)); memset (flag, 0, sizeof (flag)); for (int i=0; i<=n; i++) {w[i][i] = INF; for (int j=i+1; j<=n; j + +) W[i][j]=w[j][i]=inf; }}double directed_mst (int u)//u represents the root node {double ans=0; memset (Vis, 0, sizeof (VIS)); while (true) {//asks for the shortest arc set E for (int i=1; i<=n; i++) if (I!=u&&!flag[i]) { W[i][i]=inf, pre[i] = i; for (int j=1; j<=n; J + +) if (!flag[j] && w[j][i]<w[pre[i]][i]) {pre[i] = j; } if (pre[i]==i) return-1;//can also be used to determine convex connectivity with DFS preprocessing}//To determine if E has a ring int i; for (I=1; i<=n; i++) {if (I!=u&&!flag[i]) {int j=i, cnt=0; while (j!=u && pre[j]!=i && cnt<=n) j=pre[j], ++cnt; if (J==u | | cnt>n) continue; The end can find the starting point (root) or the point has passed more than N, indicating that there is no forward ring Break }} if (I>n) {for (int i=1; i<=n; i++) if (I!=u &&!flag[i]) ans+=w[pre[i]][i]; return ans; }//has a ring, which shrinks and shrinks the entire ring to a point I. int j=i; memset (Vis, 0, sizeof (VIS)); do {ans + = w[pre[j]][j], j=pre[j], vis[j]=flag[j]=true;//points within the ring, and directly to the weight of the ring to add and record, after the last to find the smallest tree figure, no need to expand the contraction point } while (j!=i); Flag[i] = false; The ring is shrunk to point I, point I still exist//contraction point at the same time, the Benquan value is changed for (int k=1; k<=n; ++k) if (vis[k])//At the ring midpoint { for (int j=1; j<=n; J + +) if (!vis[j])//points not in the ring {if (W[i][j] > W[k][j]) w I [j] = w[k][j]; if (W[j][k]<inf && w[j][k]-w[pre[k]][k] < W[j][i]) w[j][i] = w[j][k]-w[pre[k]][k ]; }}} return ans;}
Zhu, Liu algorithm: to find the minimum tree tree weights personal Understanding + personal Details "minimum tree diagram template"