题意:
有N组炸弹,2*i与2*i+1为一组,从这N组炸弹中选N个炸弹放入格子中,
要求:1.同组的炸弹不能同时放入;2.放入的炸弹不能相互引爆;3.每个炸弹有相同的半径;
让你求半径里最短中最长的。
思路:
二分答案,用2-SAT判可行性。加边时,凡是可以互相引爆的两个点互斥。
注意:
对double型二分。引入eps.
View Code
/* Problem:3622 (Bomb Game) Judge Status:Accepted RunId:6286747 Language:G++ Author:2010201211 Time:578MS Memory:2172K Len:3830B */ #include <iostream> #include <stdio.h> #include <math.h> using namespace std; #include <string.h> #define E 1000050 #define V 1000 #define eps 1e-8 double d[V][V]; int n; double minc,maxc; struct Zu { double x1,y1,x2,y2; }zu[105]; /******************2-SAT*********************/ int top,cnt,index,ecnt; bool instack[V]; int stack[V],id[V],dfn[V],low[V]; int head[V]; struct edge{ int s,t,next; }e[E]; void addedge(int u,int v){ e[ecnt].s=u; e[ecnt].t=v; e[ecnt].next=head[u]; head[u]=ecnt++; } void tarjan(int u){ int v; int tmp; dfn[u]=low[u]=++index; instack[u]=true; stack[++top]=u; for(int k=head[u];k!=-1;k=e[k].next){ v=e[k].t; if(!dfn[v]){ tarjan(v); if(low[v]<low[u]){ low[u]=low[v]; } } else if(instack[v] && dfn[v] < low[u]){ low[u]=dfn[v]; } } if(dfn[u]==low[u]){ cnt++; do{ tmp=stack[top--]; instack[tmp]=false; id[tmp]=cnt; }while(tmp!=u); } } void solve(){ top = cnt = index = 0; memset(dfn,0,sizeof(dfn)); for(int i=0;i<2*n;i++){ if(!dfn[i]) tarjan(i); } } bool Two_Sat(){ solve(); for(int i=0;i<n;i++){ if(id[i]==id[i+n]){ return 0; } } return 1; } /******************2-SAT*********************/ /*******************dist**********************/ double dis(double x1,double y1,double x2,double y2){ return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); } void Count_dist(){ minc=0x3F3F3F3F,maxc=-1; for(int i=0;i<n;i++){ for(int j=0;j<i;j++){ d[i][j]=d[j][i]=dis(zu[i].x1,zu[i].y1,zu[j].x1,zu[j].y1); minc=min(minc,d[i][j]); maxc=max(maxc,d[i][j]); d[i][j+n]=d[j+n][i]=dis(zu[i].x1,zu[i].y1,zu[j].x2,zu[j].y2); minc=min(minc,d[i][j+n]); maxc=max(maxc,d[i][j+n]); d[i+n][j]=d[j][i+n]=dis(zu[i].x2,zu[i].y2,zu[j].x1,zu[j].y1); minc=min(minc,d[i+n][j]); maxc=max(maxc,d[i+n][j]); d[i+n][j+n]=d[j+n][i+n]=dis(zu[i].x2,zu[i].y2,zu[j].x2,zu[j].y2); minc=min(minc,d[i+n][j+n]); maxc=max(maxc,d[i+n][j+n]); } } } /*******************dist**********************/ /******************build**********************/ bool build(double r){ ecnt=0; memset(head,-1,sizeof(head)); for(int i=0;i<n;i++){ for(int j=i+1;j<n;j++){ if(d[i][j]+eps<2*r){ addedge(i,j+n); addedge(j,i+n); } if(d[i][j+n]+eps<2*r){ addedge(i,j); addedge(j+n,i+n); } if(d[i+n][j]+eps<2*r){ addedge(i+n,j+n); addedge(j,i); } if(d[i+n][j+n]+eps<2*r){ addedge(i+n,j); addedge(j+n,i); } } } return Two_Sat(); } /******************build**********************/ /*************2-Search******************/ void T_search(){ double mid,l=-1,r=1000000,ans=0; while(r-l>=eps){ mid=(l+r)/2.0; if(build(mid)){ l=mid; ans=mid; } else { r=mid; } } printf("%.2lf\n",ans); } /*************2-Search******************/ int main() { //freopen("in.txt","r",stdin); while(cin >> n){ for(int i=0;i<n;i++){ cin >> zu[i].x1 >> zu[i].y1 >> zu[i].x2 >> zu[i].y2; } Count_dist(); T_search(); } return 0; }