A Star not a Tree?——poj2420 费马点退火算法(伪)

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;
}






  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值