This is the question of the minimal tree structure. 1 is the root node. you can create your own graph at the beginning.
Input n, m; indicates that there are n nodes, and the coordinates of the nodes are given in the next n rows.
In the next m line, two integers I and j are given, representing the connection between I and j. The coordinate distance between I and j is obtained, and the minimum tree structure is obtained.
This can be solved using the zhu liu algorithm.
Code:
[Cpp]
# Include <iostream>
# Include <algorithm>
# Include <string. h>
# Include <cmath>
Using namespace std;
Const int maxn = 105;
# Define INF 0x7fffffff
Double map [maxn] [maxn], visit [maxn];
Int pt [maxn] [2], n, pre [maxn];
Double Dist (int I, int j)
{
Return sqrt (pow (pt [I] [0]-pt [j] [0], 2.0) + pow (pt [I] [1]-pt [j] [1], 2.0 ));
}
Void DFS (int u)
{
Visit [u] = true;
For (int I = 1; I <= n; I ++)
If (! Visit [I] & map [u] [I] <INF)
DFS (I );
}
Bool Connected () // determines whether the connection is established. If the connection is established, there must be a minimum tree structure.
{
Memset (visit, false, sizeof (visit ));
Int I, cnt = 0;
DFS (1 );
For (I = 1; I <= n; I ++)
If (! Visit [I])
Return false;
Return true;
}
Double ZLEdmonds (){
Int I, j, k;
Bool circle [maxn];
Double ans = 0;
Memset (circle, false, sizeof (circle ));
While (true ){
For (I = 2; I <= n; I ++) {// find the shortest arc set E0
If (circle [I]) continue;
Pre [I] = I;
Map [I] [I] = INF;
For (j = 1; j <= n; j ++ ){
If (circle [j]) continue;
If (map [j] [I] <map [pre [I] [I])
Pre [I] = j;
}
}
For (I = 2; I <= n; I ++ ){
If (circle [I]) continue;
J = I;
Memset (visit, false, sizeof (visit ));
While (! Visit [j] & j! = 1 ){
Visit [j] = true;
J = pre [j];
}
If (j = 1) continue; // check whether a ring exists. if the root node is found, it indicates no ring exists.
I = j;
Ans + = map [pre [I] [I];
For (j = pre [I]; j! = I; j = pre [j]) {// I is not marked and used for subsequent point reduction.
Ans + = map [pre [j] [j];
Circle [j] = true;
}
For (j = 1; j <= n; j ++ ){
If (circle [j]) continue;
If (map [j] [I]! = INF)
Map [j] [I]-= map [pre [I] [I];
}
For (j = pre [I]; j! = I; j = pre [j]) // convert all vertices in the ring into vertex I and change the edge
For (k = 1; k <= n; k ++ ){
If (circle [k]) continue;
Map [I] [k] = min (map [I] [k], map [j] [k]);
If (map [k] [j]! = INF)
Map [k] [I] = min (map [k] [I], map [k] [j]-map [pre [j] [j]);
}
Break;
}
If (I> n) {// obtain the minimum tree weight
For (j = 2; j <= n; j ++ ){
If (circle [j]) continue;
Ans + = map [pre [j] [j];
}
Break;
}
}
Return ans;
}
Int main ()
{
Int m, I, j;
While (scanf ("% d", & n, & m )! = EOF ){
For (I = 1; I <= n; I ++)
For (j = 1; j <= n; j ++)
Map [I] [j] = INF;
For (I = 1; I <= n; I ++)
Scanf ("% d", & pt [I] [0], & pt [I] [1]);
While (m --){
Scanf ("% d", & I, & j );
Map [I] [j] = Dist (I, j );
}
If (! Connected ())
Printf ("poor snoopy \ n ");
Else
Printf ("%. 2lf \ n", ZLEdmonds ());
}
Return 0;
}
Author: aacm1992