最大最短距离问题

问题:

There are n points in the plane. Your task is to pick k points (k>=2), and make the closest points in these k points as far as possible.
输入:
For each case, the first line contains two integers n and k. The following n lines represent n points. Each contains two integers x and y. 2<=n<=50, 2<=k<=n, 0<=x,y<10000.

输出:
For each case, the first line contains two integers n and k. The following n lines represent n points. Each contains two integers x and y. 2<=n<=50, 2<=k<=n, 0<=x,y<10000.

样例输入:
3 2
0 0
10 0
0 20

样例输出:
22.36

回答:

#include<stdio.h>
#include<math.h>
#include<iostream>
#define eps 1e-7
using namespace std;

int n,k,vis[55],tmax,dp[55],ji;
int locat[55][2],map[55][55];
double dis[55][55],distan[2000];

int cmp(const void *a,const void*b)
{
    return *(double *)a>*(double *)b?1:-1;
}

void build(int mid)
{
    int i,f;
    for(i=1;i<=n;i++)
    {
        for(f=1;f<=n;f++)
        {
            if(dis[i][f] >= distan[mid]-eps)
            {
                map[i][f]=1;
            }
            else
            {
                map[i][f]=0;
            }
        }
        map[i][i]=0;
    }
}

void dfs(int id,int cnt)
{
    int tvis[55],i,f,able=0;
    for(i=id+1;i<=n;i++)
    {
        if(1 == vis[i])
        {
            able++;
        }    
    }
    if(0 == able)
    {
        tmax=max(tmax,cnt);
    }    
    if(cnt + able <= tmax)
    {
        return ;
    }
    for(i=1;i<=n;i++)
    {
        tvis[i]=vis[i];
    }
    for(i=id+1;i<=n;i++)
    {
        if(0 == tvis[i])
        {
            continue;    
        }
        if(cnt +dp[i] <= tmax)
        {
            continue;    
        }
        for(f=id+1;f<=n;f++)
        {
            vis[f]=tvis[f]&map[i][f];
        }
        dfs(i,cnt+1);
    }
}

int max_clique()
{
    int i,f;
    tmax=1;
    dp[n]=1;
    for(i=n-1;i>=1;i--)
    {
        for(f=1;f<=n;f++)
        {
            vis[f]=map[i][f];
        }    
        dfs(i,1);
        dp[i]=tmax;
        if(n == tmax)
        {
            return tmax;
        }
    }
    return tmax;
}

double bs()
{
    int l=0,r=ji,mid;
    while(l != r-1)
    {
        mid=(l+r)>>1;    
        build(mid);        
        if(k <= max_clique())
        {
            l=mid;
        }
        else
        {
            r=mid;
        }
    }
    return distan[l];
}

int main()
{
    int i,f,g,sum;
    while(scanf("%d%d",&n,&k)!=EOF)
    {
        ji=0;
        for(i=1;i<=n;i++)
        {
            scanf("%d%d",&locat[i][0],&locat[i][1]);
        }
        for(i=1;i<=n;i++)
        {
            for(f=1;f<=n;f++)
            {
                sum=0;
                for(g=0;g<2;g++)
                {
                    sum+=(locat[i][g]-locat[f][g])*((locat[i][g]-locat[f][g]));
                }
                dis[i][f]=sqrt((double)sum);
                if(i > f)
                {
                    distan[ji]=dis[i][f];
                    ji++;
                }
            }
        }
        qsort(distan,ji,sizeof(distan[0]),cmp);        
        printf("%.2lf\n",bs());
    }
    return 0;
}

时间: 2024-09-17 18:32:49

最大最短距离问题的相关文章

点到线段的最短距离

#include<bits/stdc++.h> using namespace std; const int M = 1e5+10 ; const double pi = acos(-1.0) ; int n ; double sx , sy ;//源点 double X[M] , Y[M] ; double minn = 1e18 , maxn = -1 ; double dist (int id) { return sqrt((X[id]-sx)*(X[id]-sx)+(Y[id]-sy)

poj1379+POJ2420+hdu3932(最短距离+费马点+模拟淬火算法)

Run Away Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 5632   Accepted: 1729 Description One of the traps we will encounter in the Pyramid is located in the Large Room. A lot of small holes are drilled into the floor. They look complet

任意两点间最短距离floyd-warshall ---- POJ 2139 Six Degrees of Cowvin Bacon

floyd-warshall算法 通过dp思想 求任意两点之间最短距离 重复利用数组实现方式dist[i][j] i - j的最短距离 for(int k = 1; k <= N; k++) for (int i = 1; i <= N; i++) for (int j = 1; j <= N; j++) dist[i][j] = min(dist[i][j], dist[i][k]+dist[k][j]); 非常好实现 O(V^3) 这里贴一道刚好用到的题 http://poj.org

求DAG上两点的最短距离

Problem 给出一个不带边权(即边权为1)的有向无环图(unweighted DAG)以及DAG上两点s, t,求s到t的最短距离,如果无法从s走到t,则输出-1. Solution DFS,BFS都可,对于unweighted DAG, BFS更合适,下面给出DFS解法. const int N(1e5+5); vector<int> g[N]; int d[N], vis[N]; void dfs(int u, int t){ vis[u]=1; if(u==t){d[u]=0; re

杭电2083(简易版之最短距离)

简易版之最短距离 Time Limit : 1000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other) Total Submission(s) : 2   Accepted Submission(s) : 2 Font: Times New Roman | Verdana | Georgia Font Size: ← → Problem Description 寒假的时候,ACBOY要去拜访很多朋友,恰巧他所有朋友的家都

HDU 2083 简易版之最短距离 --- 水题

HDU 2083 简易版之最短距离 /* HDU 2083 简易版之最短距离 */ #include <cstdio> #include <algorithm> using namespace std; const int maxn = 505; int a[maxn]; int main() { #ifdef _LOCAL freopen("D:\\input.txt", "r", stdin); #endif int t; scanf(&

计蒜客模拟赛D1T2 蒜头君的树:树上节点之间最短距离和

题目链接:https://nanti.jisuanke.com/t/16446 题意: 给你一棵有n个节点的树以及每条边的长度,输出树上节点之间的最短距离和.然后进行m次操作,每次操作更改一条边的长度,分别输出每次操作后树上节点之间的最短距离和. 题解: 最短距离和 = ∑(树上每一条边被最短路经过的次数 * 这条边的长度) 一个节点到它父节点的边被经过的次数 = 该节点以及它的子孙的节点个数 * 除了该节点和它子孙之外的所有节点总个数 每一个节点以及它子孙节点的个数总和用一遍dfs保存在num

华为oj 之 蜂窝小区最短距离

/* 学习了一种新的解题方法,很巧妙,利用坐标系来解题. 参考:http://blog.csdn.net/nys001/article/details/12637201 */ 1 #include <iostream> 2 #include <fstream> 3 #include <sstream> 4 #include <cstdlib> 5 #include <cstdio> 6 #include <cstddef> 7 #in

1076: 最短距离

题目描述 在河边有N户人家,他们每天都需要到河边去打水,后来政府拔款给大家修建一个水库.每户人家到水库的最短距离为沿河方向的距离差,问如何选择水库的位置,使所有人到水库的距离和最短? 输入 第一行输入一个数字Case,表示一共有多少组测试数据. 接下来Case个测试数据块. 每个测试数据块:第一行一个数字N,表示有N户人. 接下来一行有N个数字d,表示每户人家在河流方向上的坐标. Case<=10,1<=N<=100000,0<=d<=2*10^9. 输出 对于每组测试数据,

UVA 152-Tree&#39;s a Crowd(暴力求解三维坐标求最短距离)

Tree's a Crowd Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Status Description  Tree's a Crowd  Dr William Larch, noted plant psychologist and inventor of the phrase ``Think like a tree--Think Fig'' has invented a new