Description
Luke wants to upgrade his home computernetwork from 10mbs to 100mbs. His existing network uses 10base2 (coaxial)cables that allow you to connect any number of computers together in a lineararrangement. Luke is particulary proud that he solved a nasty NP-completeproblem in order to minimize the total cable length.
Unfortunately, Luke cannot use his existingcabling. The 100mbs system uses 100baseT (twisted pair) cables. Each 100baseTcable connects only two devices: either two network cards or a network card anda hub. (A hub is an electronic device that interconnects several cables.) Lukehas a choice: He can buy 2N-2 network cards and connect his N computerstogether by inserting one or more cards into each computer and connecting themall together. Or he can buy N network cards and a hub and connect each of his Ncomputers to the hub. The first approach would require that Luke configure hisoperating system to forward network traffic. However, with the installation ofWinux 2007.2, Luke discovered that network forwarding no longer worked. Hecouldn't figure out how to re-enable forwarding, and he had never heard of Primor Kruskal, so he settled on the second approach: N network cards and a hub.
Luke lives in a loft and so is prepared torun the cables and place the hub anywhere. But he won't move his computers. Hewants to minimize the total length of cable he must buy.
Input
The first line of input contains a positiveinteger N <= 100, the number of computers. N lines follow; each gives the(x,y) coordinates (in mm.) of a computer within the room. All coordinates areintegers between 0 and 10,000.
Output
Output consists of one number, the totallength of the cable segments, rounded to the nearest mm.
来源于poj的一道简单题目,思想继承自退火法,但是由于本题费马点唯一,故只需超一个方向逼近
输入为二维平面坐标点,输出为费马点到所有坐标点距离之和。
针对网上部分程序增加宏定义,可以直接运行。
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<iostream>
#include<math.h>
using namespace std;
const double eps = 1e-5;
const int MAXN = 110000;
#define REP(i,n) for(int i=0;i<n;i++)
#define sqr(n) pow(n,2)
struct Point//坐标点
{
double x, y;
Point(double x = 0, double y = 0) :x(x), y(y) { }
};
int n;
Point ipt[MAXN];
double dis(Point& a, Point& b)
{
return sqrt(sqr(a.x - b.x) + sqr(a.y - b.y));
}
double getdis(Point& t)
{
double ret = 0;
REP(i, n)
ret += dis(t, ipt[i]);
return ret;
}
int dx[] = { 0, 0, -1, 1 };
int dy[] = { -1, 1, 0, 0 };
int main()
{
// freopen("in.txt", "r", stdin);
while (scanf("%d",&n)!=EOF)
{
Point now = Point(0, 0), pre;
double Min = 1e20, step = 2000, t;
REP(i, n)
scanf("%lf%lf", &ipt[i].x, &ipt[i].y);
while (step > eps)
{
bool ok = true;
while (ok)
{
ok = false;
REP(i, 4)
{
now.x = pre.x + dx[i] * step;
now.y = pre.y + dy[i] * step;
if ((t = getdis(now)) < Min)
{
ok = true;
pre = now;
Min = t;
}
}
}
step /= 2;
}
//cout << (int)(Min + 0.5) << endl;
cout << (int)round(Min) << endl;
}
return 0;
}