最小圓覆蓋

2022-06-20 15:09:13 字數 1275 閱讀 2765

1.首先將所有點隨機排列;

2.按順序依次將點加入已經建好的圓中,每新增乙個點就進入步驟3;

3.如果點i在當前最小圓的外部,那麼說明點i一定在前i個點構成的最小圓的邊界上(因為要保證最小圓),進入步驟4處理;如果點i在當前最小圓的內部,則返回步驟2;

4.此時已經確定點i一定在前i個點所構成的最小圓的邊界上,則直接將點i作為圓心,半徑為0,重新將前i-1個點加入到這個圓中(類似上面的步驟,不過此時求的是包含點i的前j個點的最小覆蓋圓),每加乙個點就進入步驟5;

5.如果當前j點在最小圓外部,則說明點j一定在前j個點(包含點i)構成的最小圓的邊界上(與上類似),進入步驟6;否則不需要更新,返回4;

6.此時已經確定點i,j在前j個點(包括點i)構成的圓的邊界上,直接將圓心設為點i和j的中點,直徑為兩點距離,重新把前j-1個點加入到這個圓中,每加入乙個進入7;

7.如果當前點k在最小圓的外部,則點k在前k個點(包括i,j)構成的最小圓的邊界,此時i,j,k都在次圓邊界,直接3點共圓求出圓心與半徑即可;否則無需更新,返回6;

#include//o(n),最小圓覆蓋

#define ll long long

#define met(a, x) memset(a,x,sizeof(a))

#define inf 0x3f3f3f3f

#define ull unsigned long long

using namespace std;

const double eps = 1e-12;

struct node s[500005];

node o;//圓心座標

double ri;//半徑

double dis(node a, node b)

void getr(node p1, node p2, node p3)

int main()

random_shuffle(s + 1, s + n + 1);

o = s[1];

ri = 0;

for (int i = 2; i <= n; i++) }}

}}

}cout << fixed << setprecision(10) << ri << endl;

cout << fixed << setprecision(10) << o.x << ' ' << fixed << setprecision(10) << o.y << endl;

return 0;

}

最小圓覆蓋

最小圓覆蓋。神奇的隨機演算法。當點以隨機的順序加入時期望複雜度是線性的。algorithm a 令ci表示為前i個點的最小覆蓋圓。當加入新點pi時如果pi不在ci 1裡那麼pi必定在ci的邊界上。b 再從新考慮這樣乙個問題,ci為前i個點最小覆蓋圓且p在ci的的邊界上!同理加入新點pi時如果p i不...

最小圓覆蓋

最小圓覆蓋問題 在乙個平面上,給出 n 個點,求包圍這些點的最小圓,輸出圓心及半徑。分析雖然可以用模擬退火或者三分套三分,這裡只講隨機增量法,隨機增量法是一種確定性演算法,隨機意義下均攤複雜度 o n 而且可以達到很高的精度 可達到 10 10 量級 有事實 如果點 p 不在集合 s 的最小圓覆蓋內...

最小圓覆蓋

本來不想學的 於是今天就碰到一道大裸題 例題 bzoj2823 求最小圓覆蓋n個點。偽 如下 把所有點隨機化,設為 x 1 y 1 x n y n 開始把圓心設為x 1 半徑設為0 for i 2ton 如果i號點在當前圓內則跳過 那麼i號點就在圓周上 把1號點和i號點作為直徑作乙個圓 for j ...