1. 程式人生 > >【2018/11/02測試T2】飛越行星帶

【2018/11/02測試T2】飛越行星帶

【題目】

傳送門

【分析】

這道題比較妙啊

把每個行星看成一個點(把 xx 軸和 y=ly=l 看成兩個特殊的點),把行星之間的距離看做邊(每個點與 xx 軸的邊為 yiy_i,與 y=ly=l 的邊為 lyil-y_i),從小到達加邊,如果發現 xx 軸和 y=ly=l 連通了,就可以把星域"隔開"了,最後加的邊就應該是飛船的直徑了

【程式碼】

#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define
N 505
#define M 300005 using namespace std; struct edge { int u,v; double w; edge(){} edge(int u,int v,double w):u(u),v(v),w(w){} }a[M]; int x[N],y[N],father[N]; bool comp(const edge &p,const edge &q) {return p.w<q.w;} int find(int x) {return x==father[x]?x:father[x]=find(father[x]);} double
dist(int i,int j) {return sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));} int main() { // freopen("planet.in","r",stdin); // freopen("planet.out","w",stdout); int n,l,i,j,tot=0; scanf("%d%d",&n,&l); for(i=1;i<=n;++i) { father[i]=i; scanf("%d%d",&x[i],&y[i]); for(j=1
;j<i;++j) a[++tot]=edge(i,j,dist(i,j)); a[++tot]=edge(0,i,y[i]); a[++tot]=edge(i,n+1,l-y[i]); } father[n+1]=n+1; sort(a+1,a+tot+1,comp); for(i=1;i<=tot;++i) { int xx=find(a[i].u); int yy=find(a[i].v); if(xx==yy) continue; father[xx]=yy; if(find(0)==find(n+1)) { printf("%.3lf",a[i].w); break; } } // fclose(stdin); // fclose(stdout); return 0; }