Carpool

时间： 1ms 内存：128M

描述：

A group of friends has just completed their CS assignments, and because of the nice weather, they decide to go to Joe's house for a BBQ. Unfortunately, after all that coding, they are too tired to walk. Fortunately, between them they have enough cars to take everyone.

Joe remembers that he needs to stop off at the supermarket along the way to buy some burgers and pop.

Jenn proposes that they stop at her house to get a frisbee.

Jim decides that he doesn't like burgers, and wants to grab a pizza along the way.

After having spent so long in the computer lab, Jerry's eyes have become very sensitive to sunlight, so he needs to stop at his house for his sunglasses.

And so it goes: each person needs to run a little errand along the way. At this rate, the friends worry that it will be dark by the time they get to Joe's house. They launch into a heated discussion to about who should go in which car to minimize the time needed for everyone to reach Joe's house. The discussion itself, of course, wastes precious time that could be better spent at the BBQ.

To help the group, you will write a program to settle the discussion by computing an optimal assignment of people to cars. The overall travel time is the maximum of the travel times of each car. An optimal assignment is one that minimizes the overall travel time.

Your program will be provided with a representation of the roads in the city, in the form of distances between major landmarks. Assume that every car always travels at 60 kilometres per hour (one kilometre per minute). Each stop (at a supermarket, someone's house, etc.) takes five minutes.

Although the friends have many cars between them, to be nice to the environment, they decide to take no more cars than necessary. Each car can take at most five people.

输入：

The first line of input contains two integers n and m, 1 ≤ n ≤ 15, 1 ≤ m ≤ 1000, the number of people in the group and the number of roads in the city. The places that must be visited along the way are numbered 1 through n. The campus is numbered 0, and Joe's house is numbered n+1. An additional m lines follow, each containing three integers describing a stretch of road. The first two integers are in the range 0 to n+1 inclusive, and describe the two places connected by the stretch of road. The third integer specifies the length of the stretch of road, in kilometres. A road may be taken in both directions. There is a sequence of roads connecting every place in the city to every other place.

输出：

Output a single integer, giving the number of minutes required for everyone to reach Joe's house using an optimal assignment of people to cars.

示例输入：

```
1 2
0 1 15
1 2 10
```

示例输出：

```
30
```

提示：

参考答案（内存最优[804]）：

```
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
int r,e,i,k,j,n,dun;
int x[300], y[300], z[300];
double a,b,c,d,w;
int main(){
while (1 == scanf("%d",&r) && r >= 0) {
for (i=0;i<r;i++) scanf("%d%d%d",&x[i],&y[i],&z[i]);
scanf("%d",&e);
n = r + e;
for (i=r;i<n;i++) scanf("%d%d%d",&x[i],&y[i],&z[i]);
dun = 0;
for (k=0;k<100000 && !dun;k++) {
dun=1;
for (i=0;i<r;i++) {
if (a*x[i]+b*y[i]+c*z[i]+d > 0) {
a -= x[i];
b -= y[i];
c -= z[i];
d -= 1;
dun = 0;
}
}
for (i=r;i<n;i++) {
if (a*x[i]+b*y[i]+c*z[i]+d <= 0) {
a += x[i];
b += y[i];
c += z[i];
d += 1;
dun = 0;
}
}
}
if (dun) printf("%lg %lg %lg %lg\n",a,b,c,d);
else printf("no solution\n");
}
assert (r == -1);
assert (1 == scanf("%d",&r) && r == -1);
assert (1 != scanf(" %c",&c));
}
```

参考答案（时间最优[12]）：

```
#include <iostream>
#include <memory.h>
#include <algorithm>
using namespace std;
long long d[17][17];
long long carcost[32768];
long long cost[32768], cost2[32768];
int main() {
int i, j, k, x, y, z, n, m;
while (cin >> n >> m) {
for (i = 0; i <= n+1; i++)
for (j = 0; j <= n+1; j++)
d[i][j] = (i==j) ? 0 : 1000000000000LL;
for (i = 0; i < m; i++) {
cin >> x >> y >> z;
d[x][y] =min(d[x][y],(long long)z);
d[y][x]= min(d[y][x],(long long)z);
}
for (k = 0; k <= n+1; k++)
for (i = 0; i <= n+1; i++)
for (j = 0; j <= n+1; j++)
d[i][j] = min( d[i][k] + d[k][j],d[i][j]);
for (i = 0; i < (1<<n); i++)
cost[i] = cost2[i] = carcost[i] = 1000000000000LL;
for (int a1 = 1; a1 <= n; a1++)
for (int a2 = 1; a2 <= n; a2++)
for (int a3 = 1; a3 <= n; a3++)
for (int a4 = 1; a4 <= n; a4++)
for (int a5 = 1; a5 <= n; a5++)
carcost[((1<<a1)|(1<<a2)|(1<<a3)|(1<<a4)|(1<<a5)) >> 1] =min( carcost[((1<<a1)|(1<<a2)|(1<<a3)|(1<<a4)|(1<<a5)) >> 1],
d[0][a1] + d[a1][a2] + d[a2][a3] + d[a3][a4] + d[a4][a5] + d[a5][n+1] +
5 * (1 + (a2 != a1) + (a3 != a2) + (a4 != a3) + (a5 != a4)));
cost[0] = 0;
for (i = 0; i < (n+4)/5; i++) {
for (j = 0; j < (1<<n); j++) if (carcost[j] < 1000000000000LL)
for (k = (1<<n)-1; (k &= ~j) >= 0; k--)
cost2[k|j] =min(cost2[k|j], max(cost[k], carcost[j]));
memcpy(cost, cost2, sizeof(cost));
}
cout << cost[(1<<n)-1] << endl;
}
return 0;
}
```

题目和答案均来自于互联网，仅供参考，如有问题请联系管理员修改或删除。