曼哈頓最小生成樹 模板題

2021-09-11 19:38:49 字數 1571 閱讀 7763

曼哈頓最小生成樹:給定二維平面上的n個點,在兩點之間連邊的代價為其曼哈頓距離,求使所有點連通的最小代價。樸素的演算法可以用o(n2)的prim,或者處理出所有邊做kruskal,但在這裡總邊數有o(n2)條,所以kruskal的複雜度變成了o(n2logn)。

結論:以乙個點為原點建立直角座標系,在每45度內只會向距離該點最近的乙個點連邊。(注意距離均為曼哈頓距離)

曼哈頓最小生成樹建邊的證明:

參考部落格①:

參考部落格②:

主要的要點:

以(x,y)為原點建立座標,對於第r1區域內的點(xi,yi)滿足條件: xi>=x,yi-xi>=y-x,(xi+yi)最小。

對於r2-4三個部分, 我們可以對點進行旋轉, 將它們轉換為 r1 內的點.

我們建邊的判斷通過樹狀陣列來維護(維護:x和y-x都大於當前點,x+y的最小值對應的點)

附上模板題**:

///#include///#include///#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#define mt(a,b) memset(a,b,sizeof(a));

using namespace std;

typedef long long ll;

typedef unsigned long long ull;

const double pi=acos(-1.0);

const double e=2.718281828459;

const ll mod=1e8+7;

const int inf=0x3f3f3f3f;

int n,k;

struct node

}}void query(int index,int minn,int s) ///index:y-x minn:x+y s:編號

}int main() ///第k大邊

///1象限建邊

build_edge();

///2象限建邊

for(int i=1;i<=n;i++)

swap(point[i].x,point[i].y);

build_edge();

///3象限建邊

for(int i=1;i<=n;i++)

point[i].x=-point[i].x;

build_edge();

///4象限建邊

for(int i=1;i<=n;i++)

swap(point[i].x,point[i].y);

build_edge();

kruskal();

return 0;

}

曼哈頓距離最小生成樹

一 前人種樹 部落格 曼哈頓距離最小生成樹與莫隊演算法 部落格 學習總結 最小曼哈頓距離生成樹 二 知識梳理 曼哈頓距離 給定二維平面上的n個點,在兩點之間連邊的代價。即distance p1,p2 x1 x2 y1 y2 曼哈頓距離最小生成樹問題求什麼?求使所有點連通的最小代價。最小生成樹的 環切...

老oj曼哈頓最小生成樹

description 平面座標系xoy內,給定n個頂點v x y 對於頂點u v,u與v之間的距離d定義為 xu xv yu yv 你的任務就是求出這n個頂點的最小生成樹。input 第一行乙個正整數n,表示定點個數。接下來n行每行兩個正整數x y,描述乙個頂點。output 只有一行,為最小生成...

最小生成樹模板

prim演算法理解可以參考部落格 prim演算法模板 int prime int v int i,j,sum 0,min,k sum是權重和 for i 1 i n i lowcost i 表明當前狀態下在u內距離v點 s中各點 距離的最小值,每個u中點s 中點 都計算 lowcost i map ...