Bomb Game
Time Limit: 10000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 317 Accepted Submission(s): 109
Robbie has cracked the game, and he has known all the candidate places of each round before the game starts. Now he wants to know the maximum score he can get with the optimal strategy.
2 1 1 1 -1 -1 -1 -1 1 2 1 1 -1 -1 1 -1 -1 1
1.41 1.00
Statistic | Submit | Discuss | Back
#include<cstdio>
#include<cstring>
#include<cmath>
const double eps=1e-7;//注意这个要开大
struct T_T
{
int x,y;
}q[505];
struct Node
{
int adj,next;
}node[505*505];
struct TT
{
int DFN,LOW;
int belongs;
}num[505];
int first[550];
int n,e;
double map[505][505];
double min,max;
bool instack[550];
int stack[550],b_cnt,idx,top;
double len(int i,int j)
{
return sqrt(1.0*(q[i].x-q[j].x)*(q[i].x-q[j].x)+1.0*(q[i].y-q[j].y)*(q[i].y-q[j].y));
}
void init()
{
for(int i=1;i<=2*n;i++)
{
e=0;
first[i]=-1;
num[i].DFN=num[i].LOW=0;
num[i].belongs=0;
instack[i]=false;
}
}
void insertEdge(int u,int v)
{
node[e].adj=v;
node[e].next=first[u];
first[u]=e++;;
}
void Tarjan(int u)
{
int v;
num[u].DFN=num[u].LOW=(++idx);
instack[u]=true;
stack[++top]=u;
for(int p=first[u];p!=-1;p=node[p].next)
{
v=node[p].adj;
if(!num[v].DFN)
{
Tarjan(v);
if(num[v].LOW<num[u].LOW) num[u].LOW=num[v].LOW;
}
else
if(instack[v]&&num[v].DFN<num[u].LOW) num[u].LOW=num[v].DFN;
}
if(num[u].DFN==num[u].LOW)
{
b_cnt++;
do
{
v=stack[top--];
instack[v]=false;
num[v].belongs=b_cnt;
}while(u!=v);
}
}
bool Tarjan_SCC()
{
b_cnt=top=idx=0;
for(int i=1;i<=2*n;i++)
if(!num[i].DFN) Tarjan(i);
for(int i=1;i<=n;i++)
if(num[i].belongs==num[i+n].belongs) return false;
return true;
}
bool check(double d)
{
init();
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
{
if(map[i][j]<d) insertEdge(i,j+n),insertEdge(j,i+n);
if(map[i][j+n]<d) insertEdge(i,j),insertEdge(j+n,i+n);
if(map[i+n][j]<d) insertEdge(i+n,j+n),insertEdge(j,i);
if(map[i+n][j+n]<d) insertEdge(i+n,j),insertEdge(j+n,i);
}
return Tarjan_SCC();
}
double solve()
{
double ans=min;
while(fabs(max-min)>=eps)
{
double mid=(min+max)/2;
if(check(mid))
{
if(ans<mid) ans=mid;
min=mid;
}
else max=mid;
}
return ans;
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
for(int i=1;i<=n;i++) //处理重点?
{
scanf("%d%d",&q[i].x,&q[i].y);
scanf("%d%d",&q[i+n].x,&q[i+n].y);
}
min=1000000.00,max=-1.0;
for(int i=1;i<=2*n;i++)
for(int j=1;j<=2*n;j++)
{
double l=len(i,j);
if(l>max) max=l;
if(l<min) min=l;
map[i][j]=l;
}
printf("%0.2lf/n",solve()/2);
}
return 0;
}