平面上有 \(n\) 個點,第 \(i\) 個點座標為 \((x_i, y_i)\)。連線 \(i, j\) 兩點的邊權為 \(\sqrt\)。求最小生成樹的邊權之和。
第一行乙個整數 \(n\)。
接下來 \(n\) 行,每行輸入兩個整數 \(x_i, y_i\)。
輸出一行乙個實數,表示答案。
當你的答案與標準輸出的絕對誤差或相對誤差在 \(10^\) 內時,就會被視為正確。
4
0 01 2
-1 2
0 4
6.472136
該樣例中,最小生成樹如下圖所示:
對於 \(50\%\) 的資料,\(n \le 5000\)。
對於 \(100\%\) 的資料,\(3 \le n \le 10 ^ 5\),\(\lvert x_i \rvert, \lvert y_i \rvert \le 10 ^ 5\)。
邊數太多,肯定不能用 \(kruskal\)
\(n^2\) 的 \(prim\) 也過不去
所以可以用 \(boruvka\) 演算法
找到某乙個點距離最近的點用 \(kdtree\) 查詢就行了
查詢的時候加乙個剪枝,初始的答案不要置為無窮大,要設為當前聯通塊內的最優解
#include#include#include#include#define rg register
inline int read()
while(ch>='0' && ch<='9')
return x*fh;
}const int maxn=1e5+5;
int cnt,orz,n,rt,x[maxn],y[maxn];
struct kdt
tmp=mindis(da,xx,yy);
if(tmp>=nans) return;
rg long long tmp1=0x3f3f3f3f3f3f3f3f,tmp2=0x3f3f3f3f3f3f3f3f;
if(tr[da].lc) tmp1=mindis(tr[da].lc,xx,yy);
if(tr[da].rc) tmp2=mindis(tr[da].rc,xx,yy);
if(tmp1nans) else if(bes2[tmp]==nans)
} for(rg int i=1;i<=n;i++)
} for(rg int i=1;i<=n;i++)
} printf("%.6f\n",ans);
return 0;
}
歐幾里得的遊戲 洛谷p1290
歐幾里德的兩個後代stan和ollie正在玩一種數字遊戲,這個遊戲是他們的祖先歐幾里德發明的。給定兩個正整數m和n,從stan開始,從其中較大的乙個數,減去較小的數的正整數倍,當然,得到的數不能小於0。然後是ollie,對剛才得到的數,和m,n中較小的那個數,再進行同樣的操作 直到乙個人得到了0,他...
洛谷P1576 最小花費
在n個人中,某些人的銀行賬號之間可以互相轉賬。這些人之間轉賬的手續費各不相同。給定這些人之間轉賬時需要從轉賬金額裡扣除百分之幾的手續費,請問a最少需要多少錢使得轉賬後b收到100元。輸入格式 第一行輸入兩個正整數n,m,分別表示總人數和可以互相轉賬的人的對數。以下m行每行輸入三個正整數x,y,z,表...
洛谷 P2085 最小函式值
有n個函式,分別為f1,f2,fn。定義fi x ai x 2 bi x ci x n 給定這些ai bi和ci,請求出所有函式的所有函式值中最小的m個 如有重複的要輸出多個 輸入格式 輸入資料 第一行輸入兩個正整數n和m。以下n行每行三個正整數,其中第i行的三個數分別位ai bi和ci。ai 10...