每对点选一个,2-SAT问题,不知怎么处理半径的问题,看到网上说二分,想了想,用二分找出每个半径的可能性,一直找到最大的,用链表写了,结果Memory Limit Exceeded,,
#include<cstdio> #include<cstring> #include<cmath> #include<stack> #define N 500 const double eps=1e-10; using namespace std; int n,low[N],dfs[N],ins[N],idx,ans,belong[N],num,first[N]; double map[N][N]; struct eage { int ed,next; }E[N*N]; struct node { int x,y; }NM[N]; void addeage(int x,int y) { E[num].ed=y; E[num].next=first[x]; first[x]=num++; } double dis(node a,node b) { return sqrt(1.0*((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y))); } void inst() { memset(dfs,-1,sizeof(dfs)); memset(low,0,sizeof(low)); memset(first,-1,sizeof(first)); memset(belong,0,sizeof(belong)); ans=idx=1;num=0; } stack<int>Q; void Tarjan(int x) { int v; dfs[x]=low[x]=idx++; Q.push(x); ins[x]=1; for(int p=first[x];p!=-1;p=E[p].next) { v=E[p].ed; if(dfs[v]==-1) { Tarjan(v); low[x]=low[x]>low[v]?low[v]:low[x]; } else if(ins[v]==1) { low[x]=low[x]>dfs[v]?dfs[v]:low[x]; } } if(low[x]==dfs[x]) { while(1) { v=Q.top(); Q.pop(); ins[v]=0; belong[v]=ans; if(v==x)break; } ans++; } } int judge(double d) { int i,j; inst(); for(i=0;i<n;i++) for(j=i+1;j<n;j++) { if(map[i][j]<d){addeage(i,j+n);addeage(j,i+n);} if(map[i][j+n]<d){addeage(i,j);addeage(j+n,i+n);} if(map[i+n][j]<d){addeage(i+n,j+n);addeage(j,i);} if(map[i+n][j+n]<d){addeage(i+n,j);addeage(j+n,i);} } for(i=0;i<2*n;i++) { if(dfs[i]==-1) Tarjan(i); } for(i=0;i<n;i++) { if(belong[i]==belong[i+n]) return 0; } return 1; } int main() { int i,j; double min,max,mmax,mid; while(scanf("%d",&n)!=-1) { for(i=0;i<n;i++) scanf("%d%d%d%d",&NM[i].x,&NM[i].y,&NM[i+n].x,&NM[i+n].y); min=9999999; max=-1; for(i=0;i<2*n;i++) for(j=i+1;j<n*2;j++) { double d=dis(NM[i],NM[j]); if(min>d)min=d; if(max<d)max=d; map[i][j]=map[j][i]=d; } mmax=min; while(fabs(max-min)>=eps) { mid=(max+min)/2; if(judge(mid)) { if(mmax<mid)mmax=mid; min=mid; } else max=mid; } printf("%.2f\n",mmax/2); } return 0; }