1. 程式人生 > >Maximum Shortest Distance 最大團 二分答案 HDU 3585

Maximum Shortest Distance 最大團 二分答案 HDU 3585

names 第一次用 class sta using 一次 -i for memset

題意:給出n個點 要求取k個點 這k個點中 距離最小的兩個點要求距離最大

拿到手看不出是最大團 也看不出是二分答案(第一次用)

因為答案必然存在 一定有一個最值 所以用二分答案來做

最大距離為根號二乘10000 所以R=20000

且R-L>1e-4;

#include<bits/stdc++.h>
using namespace std;

#define N 60

int n;
int mp[N][N];
int ans;
int alt[N][N];
int Max[N];
struct
{
    int x,y;
}a[N];

bool dfs(int cur,int
tot)//cur是s1集合的個數 { if(0==cur) { if(tot>ans) { ans=tot;return true; } return false; } for(int i=0;i<cur;i++) { if( tot+cur-i<=ans )return false; int u=alt[tot][i]; if( Max[u]+tot<=ans )return false;
int next=0; for(int j=i+1;j<cur;j++) if(mp[u][ alt[tot][j] ])alt[tot+1][next++]=alt[tot][j]; if(dfs(next,tot+1)) return 1; } return 0; } int maxclique(void) { ans=0; memset(Max,0,sizeof(Max)); for(int i=n-1;i>=0;i--) { int cur=0; for
(int j=i+1;j<n;j++)if(mp[i][j])alt[1][cur++]=j;//1為s1集合 dfs(cur,1); Max[i]=ans; } return ans; } void built(double mid) { for(int i=0;i<n;i++) for(int j= 0;j<n;j++) { double t=sqrt( (a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y) ); if( t>=mid )mp[i][j]=1; else mp[i][j]=0; } } int main() { int k; while(2==scanf("%d%d",&n,&k)) { for(int i=0;i<n;i++) scanf("%d%d",&a[i].x,&a[i].y); double L=0,R=20000; while(R-L>1e-4) { double mid=(L+R)/2; built(mid); if(maxclique()>=k)L=mid; else R=mid; } printf("%.2lf\n",L); } return 0; }

Maximum Shortest Distance 最大團 二分答案 HDU 3585