• HDU3585 最大团+二分


    maximum shortest distance

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 1777    Accepted Submission(s): 589


    Problem Description
    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.
     
    Input
    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.
     
    Output
    For each case, output a line contains a real number with precision up to two decimal places.

     
    Sample Input
    3 2
    0 0
    10 0
    0 20
     
    Sample Output
    22.36
     
    Author
    alpc50

     题意:

    给出n个点,问从中取哪k个点使得这k个点中每两个点之间的距离的最小值最大,输出这个距离。

    代码:

    //求最小值最大一般用二分。此题求出每两点之间的距离,然后二分距离,两点之间的距离大于等于此二分值的点之间连线,
    //重新建图,求新图的最大团是否大于等于k。这道题可以不直接二分距离,给距离排序二分下标即可。套最大团模板。
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    int n,best,m;
    int mp[52][52],num[52];
    double dis[2502],tmp[52][52],x[52],y[52];
    bool dfs(int s[],int sum,int cnt)
    {
        if(sum==0){
            if(cnt>best){
                best=cnt;
                return 1;
            }
            return 0;
        }
        int t[102];
        for(int i=0;i<sum;i++){
            if(cnt+(sum-i)<=best) return 0;
            if(cnt+num[s[i]]<=best) return 0;
            int k=0;
            for(int j=i+1;j<sum;j++){
                if(mp[s[i]][s[j]]) t[k++]=s[j];
            }
            if(dfs(t,k,cnt+1)) return 1;
        }
        return 0;
    }
    bool Maxt(int M)
    {
        //if(n<=0) return 0;
        int s[102];
        best=0;
        memset(mp,0,sizeof(mp));
        for(int i=0;i<n;i++) 
            for(int j=i+1;j<n;j++)
                if(tmp[i][j]>=dis[M]) mp[i][j]=mp[j][i]=1;
        for(int i=n-1;i>=0;i--){
            int k=0;
            for(int j=i+1;j<n;j++){
                if(mp[i][j]) s[k++]=j;
            }
            dfs(s,k,1);
            num[i]=best;
            if(best>=m) return true;
        }
        return false;
    }
    int main()
    {
        while(~scanf("%d%d",&n,&m)){
            int cnt=0;
            for(int i=0;i<n;i++){
                scanf("%lf%lf",&x[i],&y[i]);
                tmp[i][i]=0;
                for(int j=0;j<i;j++)
                    dis[cnt++]=tmp[i][j]=tmp[j][i]=((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
            }
            sort(dis,dis+cnt);
            int ans=0;
            int L=0,R=cnt-1,M;
            while(L<=R){
                M=(L+R)/2;
                if(Maxt(M)) {L=M+1;ans=M;}
                else R=M-1;
            }
            printf("%.2lf
    ",sqrt(dis[ans]));
        }
        return 0;
    }
  • 相关阅读:
    ==和equals的区别
    Java标准库定义的常用异常
    java.lang.ArithmeticException: / by zero
    类的设计
    预处理&枚举&其他
    内存管理
    指针和字符串
    指针
    数组
    流程控制语句
  • 原文地址:https://www.cnblogs.com/--ZHIYUAN/p/6361444.html
Copyright © 2020-2023  润新知