Codeforces 672 C. Recycling Bottles(Codeforces Round #352 (Div. 2))

来源:互联网 发布:记事本软件下载 编辑:程序博客网 时间:2024/06/09 16:43

传送门

C. Recycling Bottles
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
It was recycling day in Kekoland. To celebrate it Adil and Bera went to Central Perk where they can take bottles from the ground and put them into a recycling bin.

We can think Central Perk as coordinate plane. There are n bottles on the ground, the i-th bottle is located at position (xi, yi). Both Adil and Bera can carry only one bottle at once each.

For both Adil and Bera the process looks as follows:

Choose to stop or to continue to collect bottles.
If the choice was to continue then choose some bottle and walk towards it.
Pick this bottle and walk to the recycling bin.
Go to step 1.
Adil and Bera may move independently. They are allowed to pick bottles simultaneously, all bottles may be picked by any of the two, it’s allowed that one of them stays still while the other one continues to pick bottles.

They want to organize the process such that the total distance they walk (the sum of distance walked by Adil and distance walked by Bera) is minimum possible. Of course, at the end all bottles should lie in the recycling bin.

Input
First line of the input contains six integers ax, ay, bx, by, tx and ty (0 ≤ ax, ay, bx, by, tx, ty ≤ 109) — initial positions of Adil, Bera and recycling bin respectively.

The second line contains a single integer n (1 ≤ n ≤ 100 000) — the number of bottles on the ground.

Then follow n lines, each of them contains two integers xi and yi (0 ≤ xi, yi ≤ 109) — position of the i-th bottle.

It’s guaranteed that positions of Adil, Bera, recycling bin and all bottles are distinct.

Output
Print one real number — the minimum possible total distance Adil and Bera need to walk in order to put all bottles into recycling bin. Your answer will be considered correct if its absolute or relative error does not exceed 10 - 6.

Namely: let’s assume that your answer is a, and the answer of the jury is b. The checker program will consider your answer correct if .

Examples
input
3 1 1 2 0 0
3
1 1
2 1
2 3
output
11.084259940083
input
5 0 4 2 2 0
5
5 2
3 0
5 5
3 5
3 3
output
33.121375178000
Note
Consider the first sample.

Adil will use the following path: .

Bera will use the following path: .

Adil’s path will be units long, while Bera’s path will be units long.

题目大意:
有两个人A和B捡垃圾,首先给出三个坐标,A和B的坐标,还有一个垃圾桶的坐标,然后给定一个数n,表示的有n个垃圾,然后给出n个垃圾的坐标,这两个人每次都只能最多拿一个垃圾(将垃圾放进垃圾桶中才能进行捡垃圾)可以只有一个人捡也可以两个人一起捡(半道上也是可以不捡的),让你求得是这两个人捡完全部的垃圾最短的距离。

解题思路:
(其实这是一个贪心的问题)首先分析一下,我们假设A和B两个人,他们第一次肯定先取捡垃圾,然后将垃圾放入垃圾桶之后,我们每次求的就是垃圾与垃圾桶的距离,这个距离还是很好求的,所以我们只需要求的就是第一次是只有A捡垃圾,还是只有B捡垃圾,还是A和B一起捡垃圾(这个还有就是A先捡还是B先捡),所以我们可以先求出所有垃圾距离垃圾桶的坐标的距离和,如果有人来开始捡垃圾的话,那么我们就得减去。所以我们可以标记一下,反正一共就是四种情况,设sum是每个垃圾到垃圾桶距离和的2倍,我们要求的是sum-dis[i]+disa[i]-dis[j]+disb[j]或者sum-dis[i]+disa[i]或者是sum-dis[i]+disb[i],所以求得就是 disa和disb的最大值,我们最后比较一下就行拉,具体还是详见代码:

#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cmath>#include <cstring>using namespace std;const int MAXN = 1e5+5;const double INF = 1e20+5;struct point{    double x, y;}p[MAXN],a,b,t;double get_Dis(point a, point b){    return sqrt( (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y) );}double dist[MAXN];bool vis[MAXN];double Solve(point s, int n){    double tmp = -INF, ret = 0.0;    int pos = 0;    for(int i=0; i<n; i++)    {        double tt = dist[i] - get_Dis(s, p[i]);        if(!vis[i] && tt>tmp)        {            ret = get_Dis(s, p[i]);            tmp = tt;            pos = i;        }    }    vis[pos] = true;    return ret;}int main(){    while(~scanf("%lf%lf%lf%lf%lf%lf",&a.x,&a.y,&b.x,&b.y,&t.x,&t.y))    {        int n;        scanf("%d",&n);        for(int i=0; i<n; i++)        {            scanf("%lf%lf",&p[i].x,&p[i].y);            dist[i] = get_Dis(p[i],t);        }        memset(vis, false, sizeof(vis));        double ans1 = Solve(a, n);        for(int i=0; i<n; i++)        {            if(vis[i])                ans1 += dist[i];            else                ans1 += dist[i]*2.0;        }        memset(vis, false, sizeof(vis));        double ans2 = Solve(b, n);        for(int i=0; i<n; i++)        {            if(vis[i])                ans2 += dist[i];            else                ans2 += dist[i]*2.0;        }        memset(vis, false, sizeof(vis));        double ans3 = Solve(b, n) + Solve(a, n);        for(int i=0; i<n; i++)        {            if(vis[i])                ans3 += dist[i];            else                ans3 += dist[i]*2.0;        }        memset(vis, 0, sizeof(vis));        double ans4 = Solve(a, n) + Solve(b, n);        for(int i=0; i<n; i++)        {            if(vis[i])                ans4 += dist[i];            else                ans4 += dist[i]*2.0;        }        double ans = min(min(ans1, ans2), min(ans3,ans4));        printf("%.12lf\n",ans);    }    return 0;}
0 0