最小覆蓋圓解決的問題模板大概是:
在乙個平面內的很多點中,找出乙個最小的圓,使之覆蓋所有的點。
假設點的個數為 n
nn, 最小覆蓋圓面積為 rrr。
當 n =1
n = 1
n=1 時,毋庸置疑,此時 r=0
r = 0
r=0;
當 n =2
n = 2
n=2 時,此時r應該為 r=d
is(p
oint
1,po
int2
)/2r = dis(point1, point2) / 2
r=dis(
poin
t1,p
oint
2)/2
當 n =3
n = 3
n=3 時,那麼 r
rr 就是三個點形成的最小圓,也就是三個點形成的三角形的外接圓。
那麼 n
>
3n > 3
n>
3 時呢?我們可以延續剛剛的思路
因為在取點的時候,可能第一次或者之後取的兩個點三個點做出的圓就包含了所有點, 導致所求圓面積不是最小的,所以在計算之前需要把取點的順序打亂,也就是random一下。
由於只需要三個點就可以確定乙個圓了,其圓心就是三角形的外接圓圓心(兩個點的話那就兩點中點。。),那麼我們來模擬一下過程:
① 首先,將所有點隨機排列,使用random_shuffle() 函式。
② 設此時的最小圓圓心為o0,半徑為r0。在點中取出一點 i
ii,若i在圓o0內,則遍歷下乙個點,否則就將其作為當前圓的圓心,r=0
r = 0
r=0,就是 n=1
n = 1
n=1的情況,因為我們需要構造新的圓,使之完全包括前i個點,有乙個點i了,那就還需要再找兩個。
③ 再依次取出i之前的點,作為第二個點j,如果沒有乙個是在r的外面的話就表示當前點i之前的所有的點都在我們之前計算的最小圓中,再進行下去就沒有意義,所以我們需要遍歷下乙個i點,繼續重複我們的計算,也就是i++,然後回到②。每當遇到乙個不在r中的點,這時的 r=d
is(i
,j)/
2r = dis(i, j) / 2
r=dis(
i,j)
/2,就是 n=2
n = 2
n=2 的情況,然後就進行下一步。
④ 依次取出j之前的所有點, 作為第三個點k,同樣地,如果沒有乙個點在當前我們計算的最小圓的外面,那麼再進行下去也沒有意義,就需要遍歷下乙個點j,也就是 j++
j ++
j++ ,然後回到③。每當遇到乙個不在r中的點,就相當於找到了第三個點,這三個點都剛好不在我們最初計算的圓o0中,而且剛好能做出乙個圓剛剛好包含點1~k的圓且,點i、j也都在這個圓的邊界上。
那麼 k+1
j−1k + 1 ~ j - 1
k+1j−1
之間的點呢?所以我們需要繼續重複次步驟,也就是把j之前的所有點都當作一次第三個點,從而計算出能剛剛好包含前 j−1
j - 1
j−1 個點的圓同理,②、③的回溯也是這個原因,這樣一直計算到i == n的話,求出的圓就是能包含n個點的最小圓了。
所以此處只需要三重迴圈,再加三個判斷就能計算了,額這個演算法的時間複雜度。其實只有 o(n
)o(n)
o(n)
啦,算一下。
tips:
求三角形的外接圓,可以用直線方程、也可以運用引數方程,從而求得兩條直線的中垂線,其焦點即為圓心。也可以運用向量的思想求得。
實現模板:
#include
using
namespace std;
typedef
long
long ll;
const
int maxn =
1e3+10;
const
double eds =
1e-12
;struct nodenode[maxn]
;// 點
double r =0;
//半徑
doublesq(
double x)
double
dis(
double x1,
double y1,
double x2,
double y2)
intmain()
random_shuffle
(node, node + n)
;//將點隨機排列,防止好心人教你wa題
double r = node[0]
.x, l = node[0]
.y;//圓心的橫、縱座標
double x1, x2, x3, y1, y2;
for(int i =
1; i < n; i ++)}
}}}}
cout << r *
2.0<<
"\n"
;return0;
}
最小覆蓋圓的增量演算法
題意 給出平面上的一些點,要求用乙個最小的圓,把所有的點包圍起來。最小覆蓋圓,增量法 假設圓o是前i 1個點得最小覆蓋圓,加入第i個點,如果在圓內或邊上則什麼也不做。否,新得到的最小覆蓋圓肯定經過第i個點。然後以第i個點為基礎 半徑為0 重複以上過程依次加入第j個點,若第j個點在圓外,則最小覆蓋圓必...
hdu3007 最小覆蓋圓問題
題目 buried memory 最小圓覆蓋,很經典的問題。題目大概是,平面上n個點,求乙個半徑最小的圓,能夠覆蓋所有的點。如果要求乙個最小覆蓋圓,這個圓至少要由三個點確定。有一種演算法就是任意取三個點作圓,然後判斷距離圓心最遠的點是否在圓 內,若在,則完成 若不在則用最遠點更新這個圓。這裡不仔細介...
凸包和最小覆蓋圓問題
給出平面上的一些點,求覆蓋這些點的最小圓。具體問題可以見hdu 2215。具體解法是,先求凸包,然後列舉凸包上任意3個點,若列舉的三個點構成鈍角三角形,則最大半徑為最長邊的一半 否則,半徑r a b c 4 s 其中s是面積,具體面積可以用叉乘求得,s 向量a叉乘向量b 的絕對值的一半。view c...