题目描述
15%
贪心,考虑前2000整数秒,每次构出MST再判断
话说我考试是只写了二维欧几里得距离居然没挂
25%
因为有一个数据点是方向速度相同,所以根据物体的相对运动可以得出所有的行星是相对静止的
于是printf(“1\n”)
加上贪心就有25%
100%
题目中的时间可能不是整数(考试是居然没想到)
假设当前的MST方案为s,则MST为s的时间一定是一个时间段[l,r]
显然不可能有多段时间(感性理解)
于是考虑二分往后找,每次找一个不同与当前MST的方案
由于是完全图,所以prim比Kruskal要快
原来我之前一直打的都是N^3的prim
code
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define Len 2000
#define e 3e-5
using namespace std;
int fa[51];
double x[51];
double y[51];
double z[51];
double x2[51];
double y2[51];
double z2[51];
double b[51];
int c[51];
bool bz[51][51];
int n,i,j,k,T,t,ans;
double l,r,mid;
double dis(int i,int j,double t)
{
return sqrt((x[i]+(x2[i]-x2[j])*t-x[j])*(x[i]+(x2[i]-x2[j])*t-x[j])+(y[i]+(y2[i]-y2[j])*t-y[j])*(y[i]+(y2[i]-y2[j])*t-y[j])+(z[i]+(z2[i]-z2[j])*t-z[j])*(z[i]+(z2[i]-z2[j])*t-z[j]));
}
bool work(double t,bool S)
{
int i,j,k,l;
double s;
c[1]=0;
fo(i,2,n)
{
b[i]=dis(1,i,t);
c[i]=1;
}
fo(i,2,n)
{
s=23333333333;
fo(j,1,n)
if (c[j] && s>b[j])
{
s=b[j];
k=j;
}
if (S)
bz[c[k]][k]=1,bz[k][c[k]]=1;
else
if (!bz[c[k]][k])
return 0;
c[k]=0;
fo(j,1,n)
if (c[j])
{
s=dis(j,k,t);
if (s<b[j])
{
b[j]=s;
c[j]=k;
}
}
}
return 1;
}
int main()
{
while (scanf("%d",&n)!=EOF)
{
T++;
fo(i,1,n)
scanf("%lf%lf%lf%lf%lf%lf",&x[i],&y[i],&z[i],&x2[i],&y2[i],&z2[i]),fa[i]=i;
ans=0;
l=0;
while (l<Len)
{
l+=e;
r=Len;
memset(bz,0,sizeof(bz));
work(l,1);
while (r-l>e)
{
mid=(l+r)/2.0;
if (work(mid,0))
l=mid;
else
r=mid;
}
if (l<Len)
ans++;
}
printf("Case %d: %d\n",T,ans);
}
}