曼哈頓最小生成樹:給定二維平面上的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 ...