Poj1639 Picnic Planning minimum level limit Spanning Tree
Some people drive to the park for a gathering, but the park's parking space is limited, k. So these people need to drive to other people's homes, stop, and then get together. In addition, the vehicle capacity is unlimited, and the parking space in their home is also unlimited. The shortest route is required.
Is to find a minimum spanning tree, but the degree of a vertex cannot exceed k.
Ideas:
1. Retrieve the park points and find the remaining points. The smallest spanning tree contains the I-connected block.
2. Select the smallest edge adjacent to the park point in each block.
At this park point, I edge is connected.
Park points can be connected to a maximum of k points
Get the Sum value.
3. You need to obtain the Sum value of k I + 1 -->
Each time you add an edge to form a ring on the tree, then delete the edge on the ring (maximum weight) and get Sum = min (Sum, Sum + Add edge-delete edge) complexity O (n ^ 2)
Because step 3 is complex and needs to be optimized. Step 3
Optimization: first record the Max [I] value of the edge on the Vi-> Vp path that is not directly connected to the Vp
When adding an edge, add the (Vi, Vp) edge at the minimum value of cost (Vi, Vp)-Max [I ].
Enumerate the edge that is not connected to Vp in the original ViVp path and find the edge with the maximum weight;
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
Using namespace std; const int maxn = 111 + 5; const int maxe = 15000 + 5; const int INF = 460002326; # include
Map
Mp; map
: Iterator it; int car, n, cost [maxn] [maxn], sum, father [maxn]; int best [maxn]; bool vis [maxn]; bool edge [maxn] [maxn]; bool use [maxn]; void dfs (int root) // mark each vertex in a connected block with its father {for (int I = 1; I
Dis [I]) {Min_ I = I; Min = dis [I] ;}} if (Min = INF) break; sum + = Min; vis [Min_ I] = true; use [Min_ I] = true; // mark the vertex edge used by the connected block [Min_ I] [num [Min_ I] = edge [num [Min_ I] [Min_ I] = true; for (int I = 0; I
Cost [I] [Min_ I]) {num [I] = Min_ I; dis [I] = cost [I] [Min_ I] ;}} Min = INF; int root =-1; for (int I = 0; I
Cost [father [j] [j]) best [j] = tmp; else best [j] = j;} else best [j] = j; // connect the parent node to the source node and assign j to return best [j];} void solve () {int mst = 0; memset (father,-1, sizeof (father); memset (use, 0, sizeof (use); memset (edge, false, sizeof (edge); use [0] = true; for (int I = 0; I
Cost [0] [j]-cost [ax] [bx]) // cost [0] [j] indicates the added edge cost [ax] [bx] indicates the disconnected edge {minadd = cost [0] [j]-cost [ax] [bx]; // update the reduced value and the connection point change = j ;}} if (minadd> = 0) // the minimum sum value break has been obtained to increase the sum value; sum + = minadd; // update ax = best [change]; bx = father [ax]; cost [ax] [bx] = cost [bx] [ax] = INF; father [change] = 0; cost [0] [change] = cost [change] [0] = INF ;}} int main () {int t; // freopen ("in.txt", "r", stdin); cin> t; mp. clear (); string s1, s2; int val; for (int I = 0; I
> S1> s2> val; it = mp. find (s1); // map if ing value if (it = mp. end () mp [s1] = n ++; it = mp. find (s2); if (it = mp. end () mp [s2] = n ++; if (cost [mp [s1] [mp [s2]> val) // There may be duplicate edges. Actually no ..... Cost [mp [s1] [mp [s2] = cost [mp [s2] [mp [s1] = val;} cin> car; solve (); cout <"Total miles driven:" <