Link:
http://poj.org/problem?id=1639
Topic:
Picnic planning
Time limit:5000ms Memory limit:10000k
Total submissions:7780 accepted:2726
Description
The Contortion brothers are a famous set of circus clowns, known worldwide for their incredible ability to cram a Unlimi Ted number of themselves into even the smallest vehicle. During the off-season, the "brothers" like "Get Together" for a annual contortionists meeting at a local park. However, the brothers are not only tight with regard to cramped quarters, but and money as a, so they try to find the Way to get the everyone to the party which minimizes the number of miles put on everyone's cars (thus saving gas, wear and tea R, etc.). To that end they are willing to cram themselves into as few cars as necessary to minimize the total number of miles put on All their cars together. This is often results in many brothers driving to one brother's house, leaving all but one car there and piling into the Rema Ining one. There is a constraint at the park, however:the parking lot at the picnic site can only hold a limited # of cars, so That must is factored into the overall miserly calculation. Also, due to a entrance fee to the "Park, once any brother's car arrives at the" Park it is there to stay; He won't drop off his passengers and then leave to pick up the other brothers. Now for your average circus clan, solving this problem are a challenge, so it are left to write a program to solve th Eir milage minimization problem.
Input
Input would consist of one problem instance. The A single integer n indicating the number of highway connections between brothers or between BR Others and the park. The next n lines would contain one connection per line, the form name1 name2 Dist, where name1 and name2 are either the Names of two brothers or the word Park and a brother ' s name (in either order), and Dist is the integer distance between th Em. These roads'll all are 2-way roads, and dist'll always be positive. The maximum number of brothers would be and the maximumlength of any name would be characters. Following these n lines'll be one final line containing a integer s which specifies the number of cars which can fit in The parking lot of the picnic site. You could assume that there are a path from every brother's house to the park and that's a solution exists for each problem ins Tance.
Output
Output should consist of one line of the form
Total Miles Driven:xxx
where xxx is the total number of miles driven by the "brothers" cars.
Sample Input
10
Alphonzo Bernardo 32
Alphonzo Park 57
Alphonzo Eduardo 43
Bernardo Park 19
Bernardo Clemenzi 82
Clemenzi Park 65
Clemenzi Herb 90
Clemenzi Eduardo 109
Park Herb 24
Herb Eduardo 79
3
Sample Output
Total Miles driven:183
Source
East-North America 2000
The main effect of the topic:
Circus clowns have a supernatural ability, no matter how small a car is, they can drill in, that is, a car can accommodate the infinite clown.
Now clowns are going to a park picnic, they live in different places, in order to save money (oil), to make all cars add up to walk the smallest, then, clown a
Can drive directly to the park, or drive to clown B home, and then parked in B, take the B car together to the park.
The Clown Home parking space is limited, but Park parking is limited, the park can only stop K car. Once a clown drives to the park, he must stop in the park and not go back and carry the other clowns.
Ask all clowns to drive the shortest total distance.
Analysis and Summary:
The extension problem of the minimum spanning tree, the classical minimum limit spanning tree problem.
I got it from last night. The idea is easier to understand, but the code is more complex to implement and not complete independently.
Resources:
1. This ppt is really good, see basically understand:
Http://wenku.baidu.com/view/70ef0e00eff9aef8941e06db.html
2.IOI2004 National Team Thesis--Wang Ding The extension of the problem of minimum spanning tree
Http://wenku.baidu.com/view/41800d66ddccda38376bafac.html
3. Black Book, p300~303, more difficult to understand
4. Code reference:
Http://www.cnblogs.com/ylfdrib/archive/2010/08/21/1805505.html
More Wonderful content: http://www.bianceng.cnhttp://www.bianceng.cn/Programming/sjjg/
Code:
/******************************************* minimum limit Spanning tree algorithm framework: 1. First, the minimum m-degree limit spanning tree is obtained; 2.
The minimum m-degree limit spanning tree is obtained by minimizing the m+1 of the spanning tree. 3. When DT (V0) =k stop (that is, when the V0 of the degree of K-time stop); ********************************************/#include <algorithm> #inclu de<iostream> #include <string> #include <map> #include <cstdio> #include <cstring> usi
NG namespace Std;
Map<string, int>mp; const int VN = 30; Number of points of the const int EN = VN*VN;
Number of sides const int INF = 0x7fffffff;
int limit;
Template<typename type> class prim{public:void init (int _n) {for (int i=1; i<vn-1; ++i) {
W[i][i] = INF;
for (int j=i+1; j<vn; ++j) W[i][j]=w[j][i]=inf;
} void Setvertexnum (int x) {n = x;
void insert (int u, int v, Type weight) {if (w[u][v]>weight) w[u][v] = weight;//Note there may be duplicate edges} Type mindegreest (int v0, int k) {V0 is the limiting point, K is the limit of degrees memset (father,-1, sizeof (father));
memset (Vis, 0, sizeof (VIS));
memset (Edge, 0, sizeof (EDGE));
Vis[v0] = true; int m = 0; Number of connected branches MST = 0;
Answer/* Step 1: First find the M limit tree/for (int i=1; i<=n; ++i) if (!vis[i)) {++m;
MST + prim (i, v0);
}/* Step 2: Get m+1 limit tree by M limit tree/int Minadd, A, B, TMP; int change;
The largest edge of the return path, used for exchanging for (int i=m+1; i<=k&&i<=n; ++i) {memset (best, 1, sizeof (best));
for (int j=1; j<=n; ++j) if (best[j]==-1 && father[j]!=v0) {Best (J, V0);
} minadd = INF;
for (int j=1; j<=n; ++j) if (W[v0][j]!=inf && father[j]!=v0) {//traverse all edges a = best[j];
b = Father[best[j]];
TMP = W[v0][j]-w[a][b]; if (tmp < Minadd) {
minadd=tmp;
Change = j; } if (minadd >= 0) break;
For degrees not greater than k limit, if k limit, do not have to break the MST = Minadd;
A = Best[change];
b = Father[change];
W[A][B] = w[b][a] = INF;
Father[a] = b = V0;
W[A][B] = W[b][a] = W[change][v0];
W[v0][change] = w[change][v0] = INF;
return MST; Private://La Cheng has root tree void dfs (int cur) {for (int i=1; i<=n; ++i) if (mark[i) && EDG
E[i][cur]) {father[i] = cur;
Mark[i] = 0;
DFS (i);
}//Memory search, x to the V0 path on the most weighted edge int best (int x, int V0) {if (father[x]==v0) return-1;
if (Best[x]!=-1) {return best[x];
int tmp = Best (father[x], V0); if (Tmp!=-1 && w[tmp][father[tmp]] > w[father[X]][X]) best[x] = tmp;
else best[x] = x;
return best[x];
/* seek to remove the minimum spanning tree/Type prim (int s, int V0) {memset (mark, False, sizeof (mark)) of the connected components after the edges connected to the V0;
Vis[s] = Mark[s] = true;
for (int i=1; i<=n; ++i) {key[i] = W[s][i]; Pre[i] = s;
int sum=0;
for (int i=1; i<n; ++i) {int u=-1; for (int j=1; j<=n; ++j) if (!vis[j]&&!mark[j)) {if (u==-1| |
Key[j]<key[u]) u=j;
} if (u==-1) break;
Vis[u] = Mark[u] = true;
Edge[pre[u]][u] = Edge[u][pre[u]] = true;
Sum + + w[pre[u]][u]; for (int j=1; j<=n; ++j) if (!vis[j]&&!mark[j]) {if (key[j]>w[u][j)) {Ke Y[J] = W[u][j];
PRE[J] = u;
int Min = INF; int root =-1; Treeroot for (int i=1; i<=n; ++i) if (Mark[i] && w[i][v0]<min) {Min = W[i][v0];
root = i;
The//La Cheng has a root tree that connects the current connected component to the smallest edge of the V0 weight and makes up a tree, saves the parent node Mark[root with a father array) = 0;
DFS (root);
Father[root] = V0;
return sum + Min; } private:int N; Number of nodes int PRE[VN]; parent node int FATHER[VN]; Parent node in the spanning tree bool EDGE[VN][VN]; EDG[I][J] = True to indicate that the edge [i,j] is already int best[vn in the spanning tree]; Best[i] preserves the V0 to the largest side of the weights between VIS[VN]; Vis[i] Indicates whether point I is adding to the spanning tree bool MARK[VN]; The tag Type MST used to find the minimum spanning tree of the connected component;
Save Answer Type W[VN][VN], KEY[VN];
};
prim<int>g;
int main () {int n, d, a, B;
String name1,name2;
mp["Park"] = 1;
scanf ("%d", &n);
G.init (n);
int cnt=1; for (int i=0; i<n; ++i) {cin >> name1 >> name2 >> D;
A=MP[NAME1];
B=MP[NAME2];
if (!a) a=mp[name1]=++cnt;
if (!b) b=mp[name2]=++cnt;
G.insert (A,B,D);
G.insert (B,A,D);
G.setvertexnum (CNT);
scanf ("%d", &limit);
printf ("Total miles driven:%d\n", g.mindegreest (1, limit));
return 0; }
Author: csdn Blog shuangde800