Question meaning:
There are n villages in different coordinates and heights. Now we need to supply water to all the villages, as long as there is a road between the two villages. The distance between the water pipes is the Euclidean distance between the coordinates, the cost is the difference between the altitude and the distance. Now the scheme is required to minimize the cost to the distance. Obviously, this question requires an optimal rate spanning tree.
0-1 plan:
Concept
There is a weighted graph G. For each e [I] in the graph, there are benifit [I] (revenue) and cost [I] (cost ), what we need is a spanning tree T, which makes Sigma (benifit [I])/Σ (cost [I]), iε T maximum (or minimum ). this is obviously a practical issue.
Solution 1: 0-1 score Planning
If x [I] is equal to 1 or 0, it indicates whether edge e [I] belongs to the Spanning Tree.
Then the ratio r = Σ (benifit [I] * x [I])/Σ (cost [I] * x [I]), 0 ≤ I <m.
To maximize r, design a subproblem ---> let z = Σ (benifit [I] * x [I]) -l * Σ (cost [I] * x [I]) = Σ (d [I] * x [I]) the maximum value (d [I] = benifit [I]-l * cost [I]) is z (l ). we can happily regard z (l) as the total weight of the largest spanning tree with d as edge weight.
Then define two properties:
1. monotonically decreasing z
Proof: Because cost is a positive number, z increases with the decrease of l.
2. z (max (r) = 0
Proof: If z (max (r) <0, Σ (benifit [I] * x [I])-max (r) * sigma (cost [I] * x [I]) <0, which can be converted to max (r) <max (r ). conflict;
If z (max (r) is greater than or equal to 0, the r is the largest when z is equal to 0.
Code:
If variables are followed by binary and iteration. If 0 is binary, if 1 is iteration, iteration is 300 ms +, and binary is 1400 ms +
[Cpp]
# Include <stdio. h>
# Include <stdlib. h>
# Include <string. h>
# Include <math. h>
# Define nMax 1050
# Define inf 0x7fffffff
Static double eps = 1e-4;
Int vis [nMax], x [nMax], y [nMax], z [nMax], pre [nMax];
Double dis [nMax], cost [nMax] [nMax], dist [nMax] [nMax];
Int n;
Double prim (double x) // calculate the minimum spanning tree using the split Algorithm
{
Double totalcost = 0, totaldist = 0;
Double sum = 0.0;
For (int I = 1; I <= n; ++ I)
{
Pre [I] = 1;
}
Dis [1] = 0;
Memset (vis, 0, sizeof (vis ));
Vis [1] = 1;
For (int I = 2; I <= n; ++ I)
{
Dis [I] = cost [1] [I]-dist [1] [I] * x;
}
Int k;
For (int I = 2; I <= n; ++ I)
{
Double minCost = inf;
For (int j = 2; j <= n; ++ j)
{
If (! Vis [j] & dis [j] <minCost)
{
MinCost = dis [j];
K = j;
}
}
Vis [k] = 1;
Sum + = minCost; // for Binary
Totalcost + = cost [pre [k] [k];
Totaldist + = dist [pre [k] [k];
For (int j = 1; j <= n; ++ j)
{
If (! Vis [j] & dis [j]> cost [k] [j]-dist [k] [j] * x)
{
Dis [j] = cost [k] [j]-dist [k] [j] * x;
Pre [j] = k;
}
}
}
# If 0 // 0 for binary, 1 for Iteration
Return totalcost/totaldist;
# Else
Return sum;
# Endif
}
Int main ()
{
While (scanf ("% d", & n), n)
{
For (int I = 1; I <= n; ++ I)
{
Scanf ("% d", & x [I], & y [I], & z [I]);
For (int j = 1; j <I; ++ j)
{
Double tmp = (x [I]-x [j]) * (x [I]-x [j]) + (y [I]-y [j]) * (y [I]-y [j]);
Cost [I] [j] = cost [j] [I] = abs (z [I]-z [j]); // altitude
Dist [I] [j] = dist [j] [I] = sqrt (tmp); // Euclidean distance
}
}
Double a = 0;
# If 0 // 1 is iteration, and 0 is binary
While (1) // calculate the maximum value through iteration
{
Double B = prim ();
If (abs (a-B) <eps)
{
Printf ("%. 3f \ n", );
Break;
}
Else
A = B;
}
# Else
Double head = 0, tail = 100000.0;
While (tail-head> 1e-5)
{
Double mid = (header + tail)/2.0;
A = prim (mid );
If (a> = 0)
{
Head = mid;
}
Else
Tail = mid;
}
Printf ("%. 3f \ n", tail );
# Endif
}
Return 0;
}