hdu 3585 maximum shortest distance(二分+最大团)
二分距离,求最大团,看是否>=K
View Code
#include<iostream> #include<algorithm> #include<string> #include<math.h> using namespace std; const int N = 50+10; int dis[N][N],dd[N*N]; int dp[N]; bool inset[N],g[N][N]; int n,best,ord[N],deg[N]; bool found; inline void Memcpy(bool *d,bool *s) { for(int i=0;i<n;i++) d[i]=s[ord[i]]; } bool cmp(int a,int b) { return deg[a]<deg[b]; } inline int find(int start,bool *s) { for(int i=start+1;i<n;i++) if(s[i]) return i; return -1; } void clique(bool *s,int start,int len) { int first=find(start,s),i; if(first==-1) { if(len>best) { best=len; found=true; } return ; } bool tmp[N]; while(first!=-1) { if(len+n-start<=best || len+dp[first]<=best) return ; tmp[first]=false; for(i=first+1;i<n;i++) tmp[i]=s[i]&g[ord[first]][ord[i]]; clique(tmp,first,len+1); if(found) return ; first=find(first,s); } } inline int get_clique(int dist) { memset(g,false,sizeof(g)); memset(deg,0,sizeof(deg)); memset(dp,0,sizeof(dp)); for(int i=0;i<n;i++) { ord[i]=i; g[i][i]=true; for(int j=i+1;j<n;j++) { if(dis[i][j]>=dist) { g[i][j]=g[j][i]=true; deg[i]++,deg[j]++; } } } sort(ord,ord+n,cmp); best=0;dp[n-1]=1; for(int i=n-2;i>=0;i--) { Memcpy(inset,g[ord[i]]); found=false; clique(inset,i,1); dp[i]=best; } return dp[0]; } struct Point { int x, y; }p[N]; inline int get_dis(Point a,Point b) { return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y); } int main() { int k; while(scanf("%d %d",&n,&k)==2) { for(int i=0;i<n;i++) scanf("%d %d",&p[i].x,&p[i].y); int t=0; for(int i=0;i<n;i++) { for(int j=i+1;j<n;j++) { dis[i][j]=dis[j][i]=get_dis(p[i],p[j]); dd[t++]=dis[i][j]; } } sort(dd,dd+t); int left=0,right=t-1,mid; while(left<=right) { mid=(left+right)>>1; if(get_clique(dd[mid])>=k) left=mid+1; else right=mid-1; } printf("%.2f\n",sqrt(double(dd[left-1]))); } return 0; }