Links: http://poj.org/problem?id=3164
Test instructions: Tells N Point coordinates, m-bars indicate a path between two points, and a graph-minimum spanning tree is established from 1 o'clock onwards.
Zhu Liu Algorithm template problem
under ========================== split line excerptSasuke_scutthe blog==================================================
The smallest tree diagram, which specifies a special point root for a weighted graph, asks for a root-rooted, forward spanning tree T, and minimizes the total weight of all edges in T. The first algorithm for the minimum tree diagram is the one proposed by Zhu Yongzin and Liuzhenhong in the 1965 for the Complexity of O (VE).
It is very simple to determine if there is a tree diagram, so it is only possible to do a graph traversal with V as the root, so the following algorithm no longer considers the absence of tree diagrams.
before all operations begin, we need to clear all the self-loops in the diagram. It is clear that the self-loop is not possible on any tree chart. Only by doing this, finally the complexity of the method is really guaranteed to be O (VE).
first for each point outside of the root, one is selected into the edge, which must be the smallest of all into the edge. Now all of the smallest incoming edges have been selected, and if there is no Shang in this set of edges, we can prove that this set is the smallest tree of the graph. The proof is not very difficult. If there is a Shang, we are going to call this an artificial vertex of the ring, and change the right side of the graph. Assuming that a certain point u is on the ring and that the Benquan that points to u in this ring are In[u], then for each edge starting from U (U, i, W), The edge of the new diagram is connected (new, I, W), where new is the newly added artificial vertex; For each edge entering u (i, u, W), Edge (I, new, W-in[u]) is established in the new diagram. Why the right to enter the edge minus In[u], this is explained later, here first gives the steps of the algorithm. Then it can be proved that the right of the smallest tree diagram in the new graph plus the right of the ring that was shrunk in the old graph is the right of the smallest tree diagram in the original image.
the above conclusions do not prove. Now, based on the above conclusions, explain why the right of the edge is not changed, the right to enter the edge minus in [u]. For the minimum tree map T in the new diagram, the edge that points to the human node is E. When the human node is expanded, E points to a ring. Assuming that the original E is pointing to u, this time we will be the ring on the edge of U in[u] Delete, so that the original image of a tree. We will find that if the right W ' (e) of E in the new diagram is the right of E in the original image (E) minus In[u], then when we remove in[u] and restore E to the original state, the right of the tree is still the right plus ring of the new graph, and this weight is the weight of the least-squares graph. So after the expansion of the node, we still get the smallest tree figure. By gradually expanding all the artificial nodes, you will get the minimum tree diagram of the initial graph.
if the implementation is very smart, you can reach the minimum incoming O (e), look for the Ring O (v), contraction O (e), where the Ring O (v) requires a bit of skill here. So the complexity of each contraction is O (E), and then it shrinks a few times? Since we have taken all the rings from the beginning, we can know that each ring contains at least 2 points and shrinks to 1 points, reducing the total number of points by at least 1. When the entire graph shrinks to only 1 points, the smallest tree diagram does not need to be asked. So we can only do V-1 shrinkage at most, so the complexity is naturally O (VE). Thus, if the self-ring is not removed at first, the theoretical complexity will be related to the number of self-loops.
======================== Split line excerpt fromSasuke_scutthe blog=====================================================
Simply put, in addition to the source point at each point to choose a minimum weight of the incoming edge, if there is a ring to indicate that there are additional edges, the ring into a point of the point of the tree, until there is no ring.
Zhu Liu algorithm template, vertex subscript starting from 0
/* Minimum tree figure template-Zhu Liu Algorithm template description: Point marking must 0-(N-1) must be removed to its own point (to its own side of the Benquan infinite) */#include <cstring> #include <string> #include <fstream> #include <iostream> #include <iomanip> #include <cstdio> #include <cctype># include<algorithm> #include <queue> #include <map> #include <set> #include <vector># include<stack> #include <ctime> #include <cstdlib> #include <functional> #include <cmath >using namespace std; #define PI ACOs ( -1.0) #define MAXN 50100#define EPS 1e-7#define INF 0x7fffffff#define seed 131#defi NE mod 1000000007#define ll long long#define ull unsigned ll#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1st ruct node{int u,v; double Dis;} Edge[10100];int pre[110],id[110],vis[110];int n,m;int x[110],y[110];d ouble in[110];d ouble Directed_MST (int root,int Nv,int NE) {DOUBLE ret = 0;while (true) {//1. Find minimum in-Edge for (int i=0;i<nv;i++) in[i] = inf;for (int i=0;i<ne;i++) {int u = EDG E[i].u;int v = edge[i].v;if (Edge[i].dis < In[v] && u! = V) {Pre[v] = u;in[v] = Edge[i].dis;}} for (int i=0;i<nv;i++) {if (i = = root) continue;if (in[i] = = INF) return-1;//The root does not reach it}//2 except the root is a bit not in the edge. Find Ring int cntnode = 0; memset (id,-1,sizeof (ID)); memset (vis,-1,sizeof (Vis)); In[root] = 0;for (int i=0;i<nv;i++) {//tag per ring ret + = In[i];int v = i;while (vis[v]! = i &&am P ID[V] = = 1 && v! = root) {Vis[v] = I;v = Pre[v];} if (v! = root && id[v] = =-1) {for (int u = pre[v]; u = v; u = pre[u]) {id[u] = Cntnode;} ID[V] = Cntnode + +;}} if (Cntnode = = 0) break;//no ring for (int i=0;i<nv;i++) if (id[i] = = 1) {Id[i] = Cntnode + +;} 3. Indent, re-mark for (int i=0;i<ne;i++) {int v = edge[i].v;edge[i].u = ID[EDGE[I].U];EDGE[I].V = Id[edge[i].v];if (edge[i].u ! = edge[i].v) {Edge[i].dis-= In[v];}} NV = Cntnode;root = Id[root];} return ret;} int main () {int i,j,a,b; Double temp; while (scanf ("%d%d", &n,&m)!=eof) {for (i=1;i<=n;i++) {scanf ("%d%d", &x[i],&y[i]); } for (I=0;i<m;i+ +) {scanf ("%d%d", &a,&b); edge[i].u = A-1; EDGE[I].V = b-1; if (a==b) Edge[i].dis = INF; else{temp = (X[a]-x[b]) * (X[a]-x[b]) + (Y[a]-y[b]) * (Y[a]-y[b]); temp = sqrt (temp); Edge[i].dis = temp; }} Double ans = directed_mst (0,n,m); if (Ans==-1) puts ("poor Snoopy"); else printf ("%.2lf\n", ans); } return 0;}