POJ 2420 A Star not a Tree? (计算几何-费马点)

A Star not a Tree?

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 3435   Accepted: 1724

Description

Luke wants to upgrade his home computer network from 10mbs to 100mbs. His existing network uses 10base2 (coaxial) cables that allow you to connect any number of computers together in a linear arrangement. Luke is particulary proud that he solved a nasty NP-complete
problem in order to minimize the total cable length.

Unfortunately, Luke cannot use his existing cabling. The 100mbs system uses 100baseT (twisted pair) cables. Each 100baseT cable connects only two devices: either two network cards or a network card and a hub. (A hub is an electronic device that interconnects
several cables.) Luke has a choice: He can buy 2N-2 network cards and connect his N computers together by inserting one or more cards into each computer and connecting them all together. Or he can buy N network cards and a hub and connect each of his N computers
to the hub. The first approach would require that Luke configure his operating system to forward network traffic. However, with the installation of Winux 2007.2, Luke discovered that network forwarding no longer worked. He couldn‘t figure out how to re-enable
forwarding, and he had never heard of Prim or Kruskal, so he settled on the second approach: N network cards and a hub.

Luke lives in a loft and so is prepared to run the cables and place the hub anywhere. But he won‘t move his computers. He wants to minimize the total length of cable he must buy.

Input

The first line of input contains a positive integer 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 are integers between 0 and 10,000.

Output

Output consists of one number, the total length of the cable segments, rounded to the nearest mm.

Sample Input

4
0 0
0 10000
10000 10000
10000 0

Sample Output

28284

Source

Waterloo Local 2002.01.26

题目大意:

求n边形的费马点。即找到一个点使得这个点到n个点的距离之和最小。

解题思路:

三角形也有费马点。三角形费马点是这样定义的:寻找三角形内的一个点,使得三个顶点到该点的距离之和最小。

三角形费马点的做法是:

(1)若有一个角大于120度。那么这个角所在的点就是费马点。

(2)若不存在。那么对于三角形ABC,任取两条边(如果AB、AC),向外做等边三角形得到C‘ 和 A‘  。那么AA‘ 和CC‘ 的交点就是费马点。

那么对于这题n多边形,我採取的策略全然不同,採用了模拟退火的做法。这样的做法相对照较简单,也能够用在求三角形费马点之中。

模拟退火算法就跟数值算法里面的自适应算法同样的道理

(1)定义好步长

(2)寻找一个起点,往8个方向的按这个步长搜索。

(3)假设找到比答案更小的点,那么以这个新的点为起点,反复(2)

(4)假设找不到比答案更小的点,那么步长减半,再尝试(2)

(5)直到步长小于要求的答案的精度就停止。

解题代码:

#include <iostream>
#include <cmath>
#include <cstdio>
using namespace std;

const int offx[]={1,1,0,-1,-1,-1,0,1};
const int offy[]={0,1,1,1,0,-1,-1,-1};
const int maxn=110;
const double eps=1e-2;

struct point{
    double x,y;
    point(double x0=0,double y0=0){x=x0;y=y0;}
    double getdis(point p){
        return sqrt( (x-p.x)*(x-p.x)+(y-p.y)*(y-p.y) );
    }
}p[maxn];

int n;

double getsum(point p0){
    double sum=0;
    for(int i=0;i<n;i++) sum+=p0.getdis(p[i]);
    return sum;
}

void solve(){
    for(int i=0;i<n;i++) scanf("%lf%lf",&p[i].x,&p[i].y);
    double ans=getsum(p[0]),step=100;
    point s=p[0],d;
    while(step>eps){
        bool flag=false;
        for(int i=0;i<8;i++){
            d=point(s.x+step*offx[i],s.y+step*offy[i]);
            double tmp=getsum(d);
            if(tmp<ans){
                s=d;
                ans=tmp;
                flag=true;
            }
        }
        if(!flag) step/=2;
    }
    printf("%.0f\n",ans);
}

int main(){
    while(scanf("%d",&n)!=EOF){
        solve();
    }
    return 0;
}
时间: 2024-12-11 11:21:51

POJ 2420 A Star not a Tree? (计算几何-费马点)的相关文章

三分 POJ 2420 A Star not a Tree?

题目传送门 1 /* 2 题意:求费马点 3 三分:对x轴和y轴求极值,使到每个点的距离和最小 4 */ 5 #include <cstdio> 6 #include <algorithm> 7 #include <cstring> 8 #include <cmath> 9 10 const int MAXN = 1e2 + 10; 11 const int INF = 0x3f3f3f3f; 12 double x[MAXN], y[MAXN]; 13 i

[POJ 2420] A Star not a Tree?

A Star not a Tree? Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4058   Accepted: 2005 Description Luke wants to upgrade his home computer network from 10mbs to 100mbs. His existing network uses 10base2 (coaxial) cables that allow you

POJ 2420 A Star not a Tree? (模拟退火)

题目地址:POJ 2420 今天在比赛遇到了这题..于是现场学了一下模拟退火.... 这题是先初始化为一个点,然后不断趋近距离和最短的点.还是挺简单的.. 代码如下: #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdlib.h> #include <math.h> #include <ctype.h&g

POJ 2420 A Star not a Tree? 爬山算法

B - A Star not a Tree? Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=88808#problem/B Description Luke wants to upgrade his home computer network from 10mbs to 100mbs. His existing network uses 10ba

poj 2420 A Star not a Tree?——模拟退火

题目:http://poj.org/problem?id=2420 精度设成1e-17,做三遍.ans设成double,最后再取整. #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<cstdlib> #include<ctime> #define db double usin

POJ 2420 A Star not a Tree?【爬山法】

题目大意:在二维平面上找出一个点,使它到所有给定点的距离和最小,距离定义为欧氏距离,求这个最小的距离和是多少(结果需要四舍五入)? 思路:如果不能加点,问所有点距离和的最小值那就是经典的MST,如果只可以加一个点问最小值就是广义的费马点的问题,如果加点的数目不加限制,那问题就成了斯坦纳树的问题(介个属于NPC问题) 这题显然就是广义费马点问题,可以采用局部贪心法,从一个初始点出发,不断向上下左右四个方向拓展,如果在一个方向上走过去到所有点的距离和小于目前这个点到所有点的距离和,那就更新目前点的值

poj 3990 Fermat Point in Quadrangle 凸包和费马点

题意: 求一个四边形的费马点. 分析: 模拟退火要么超时要么wa,这题的数据就是不想让随机算法过的..其实四边形的费马点很简单,如果是凸四边形的话费马点是对角线交点,如果是凹四边形费马点是凹点.但题目给的四个点顺序是不确定的,所以要先求下凸包. 代码: //poj 3990 //sep9 #include <iostream> #include <cmath> #include <algorithm> using namespace std; struct Point

【POJ】2420 A Star not a Tree?

http://poj.org/problem?id=2420 题意:给n个点,求一个点使得到这个n个点的距离和最短,输出这个最短距离(n<=100) #include <cstdio> #include <cstdlib> #include <cmath> #include <algorithm> using namespace std; const int N=105; struct P { int x, y; }a[N]; int n; inlin

【POJ】2420.A Star not a Tree?(模拟退火)

题解 开始学习随机化算法= = 模拟退火的板子往上套就行,莫名其妙的就过了 可能数据太水,实现的具体细节可看代码 代码 #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> //#define ivorysi #define MAXN 105 #define eps 1e-8 #define pb push_ba