Http://acm.hdu.edu.cn/showproblem.php? PID = 1, 4081
Solution report:
First, find the Minimum Spanning Tree, and record the tree. Use the low, and Pre arrays.
The DP array indicates the maximum edge. This information can be obtained when Prim is obtained.
And then enumerate any two points to repair the magic path. This path may be in the least generated tree or not.
If not, replace the longest path on the MST between the two points. DP Array
If the path directly replaced with MST is also a DP Array
View code
# Include <iostream> # Include < String . H> # Include <Stdio. h> # Include <Algorithm> # Include <Cmath> Using Namespace STD; # Define Maxn 1110 # Define INF ~ 0u> 1 Double Map [maxn] [maxn]; Double People [maxn]; Double Low [maxn]; Double Max ( Double A, Double B ){ Return A> B? A: B ;} Struct Node0 { Double X; Double Y;} node [maxn]; Double DP [maxn] [maxn]; Int N; Int Visit [maxn]; Int Pre [maxn]; Double SUM; Double Len ( Double X1, Double Y1, Double X2, Double Y2 ){ Return SQRT (x1-x2) * (x1-x2) + (y1-y2) * (Y1- Y2 ));} Void Init () {memset (people, 0 , Sizeof (People )); For ( Int I = 0 ; I <= maxn; I ++ ) For ( Int J = 0 ; J <= maxn; j ++ ) Map [I] [J] = INF; scanf ( " % D " ,& N ); For (Int I = 1 ; I <= N; I ++ ) Scanf ( " % Lf " , & Node [I]. X, & node [I]. Y ,& People [I]);} Void Map (){ For ( Int I = 1 ; I <n; I ++ ){ For (Int J = I + 1 ; J <= N; j ++ ) {Map [I] [J] = Map [J] [I] = Len (node [I]. X, node [I]. Y, node [J]. X, node [J]. Y );}}} Double Prim (){ Double Temp; Int ID; Double Ans = 0 ; Memset (visit, 0 , Sizeof (Visit); memset (DP, 0 , Sizeof (DP )); For ( Int I = 1 ; I <= N; I ++) Pre [I] = 1 ; For ( Int I = 1 ; I <= maxn; I ++) low [I] = INF; visit [ 1 ] = 1 ; For ( Int I = 2 ; I <= N; I ++ ) Low [I] = Map [ 1 ] [I]; For ( Int I = 2 ; I <= N; I ++ ) {Temp = INF; For ( Int J = 1 ; J <= N; j ++ ) If (! Visit [J] & low [J] < Temp) temp = Low [J], id = J; ans + = Temp, visit [ID] = 1 ; For ( Int J = 1 ; J <= N; j ++ ) If (Visit [J] & ID! = J) DP [ID] [J] = DP [J] [ID] = Max (DP [pre [ID] [J], temp ); For ( Int J = 1 ; J <= N; j ++ ) If (Low [J]> map [ID] [J] &! Visit [J]) low [J] = Map [ID] [J], pre [J] = ID ;} Return Ans ;} Double Solve (){ Double Temp = 0.0 ; Double Ans = 0.0 ; For ( Int I = 1 ; I <n; I ++ ) For ( Int J = I + 1 ; J <= N; j ++ ) {Temp = (People [I] + people [J])/(Sum-DP [I] [J]); ans = Max (temp, ANS );} Return Ans ;} Int Main (){ Int Test; For (CIN> test; test -- ) {Init (); Map (); sum = Prim (); printf ( " %. 2f \ n " , Solve ());} Return 0 ;}