原理:每個點在以它為頂點的45°角範圍內,只可能連向距離(曼哈頓距離)它最近的點。
證明:以點a為原點,y軸正半軸向x軸正半軸方向偏45°角為例:
如圖所示,設|ab|<=|ac| (所有距離都是曼哈頓距離)
a(0,0) b(x1,y1) c(x2,y2)
|ab|=x1+y1 |ac|=x2+y2 |bc|=|x2-x1|+|y2-y1|
即 x1+y1<= x2+y2
如果能夠證明 |bc|<=|ac| ,即|x2-x1|+|y2-y1|<= x2+y2
那麼對於abc三點,只需要a向b連邊即可。因為對c來說,至少與b連邊比與a連邊更優。
根據x1 y1 x2 y2大小分情況討論:
①x1<=x2 y1<=y2 ,此時 |ab|+|bc|=|ac|,即x1+y1+|x2-x1|+|y2-y1|=x2+y2
所以|x2-x1|+|y2-y1|=x2+y2-(x1+y1)
②x1<=x2 y1>y2 ,此時|bc|=x2-x1+y1-y2,|ac|-|bc|=x2+y2-(x2-x1+y1-y2)=x1-y1+y2*2
假設|ac|x1+y2*2
那麼|ab|=x1+y1>2*x1+2*y2 |ac|=x2+y2<=2*y2
所以|ac|>=|bc|
③x1>x2 y1<=y2 ,此時|bc|=x1-x2+y2-y1,|ac|-|bc|=x2+y2-(x1-x2+y2-y1)=y1-x1+x2*2
∵ x1>x2 且 x1+y1<= x2+y2,∴ y1
∵ b在a的y軸正半軸向右偏45°角範圍內 ∴y1>=x1
∴ x1<=y1
∴y1-x1+x2*2>0
∴ |ac|>|bc|
④x1>x2 y1>y2 不滿足|ab|<=|ac| 的假設,不存在
一共有8個45°方向,因為克魯斯卡爾演算法相當於使用雙向邊,所以是4個方向,利用座標變換到上面的方向即可
原本尋找的是區域2的點
把所有的點交換x和y座標,就統計到了 區域1的點(1 2交換 3 4交換)
再把x座標變為相反數,就統計到了區域4的點(1 4再交換 2 3再交換)
最後再交換x和y座標,就統計到了區域3的點(1 2再交換 3 4再交換)
具體實現:
對於每個點(x0,y0),我們要尋找以它為頂點,以y軸正半軸向右45°角範圍內,距離他最近的點
即滿足以下兩個條件:
1. x>=x0
2. y-x>=y0-x0
並且x+y-(x0+y0)最小的點
即滿足上述2個條件並且x+y最小的 點(x,y)
採用線段樹或者樹狀陣列維護最小值
條件1將點按x座標為第一關鍵字,y左邊按第二關鍵字,從大到小排序,依次插入樹狀陣列或者是線段樹。這樣每次查詢的時候,在樹中的點都是滿足條件1的點
條件2 每次查詢乙個點完畢後,在該點的y-x位置處,用該點的x+y更新
查詢滿足條件的最小的x+y:在大於等於當前點的y-x的區間裡,查詢最小值
然後y-x要離散化
小細節:
因為樹狀陣列更方便查詢字首情況,所以可以是離散化x-y,就變成在小於等於x-y的區間裡查詢最小值
#include#include#include
#define n 50001
#define lowbit(x) x&-x
using
namespace
std;
intxx[n],yy[n];
struct
node
e[n];
inthas[n];
intmi[n],who[n];
inttot;
struct
edge
f[n<<2
];int
fa[n];
bool
cmp1(node p,node q)
bool
cmp2(edge p,edge q)
int find(int i)
int getmin(int
x) x-=lowbit(x);
}return
whoo;
}void change(int x,int val,int to,int
n) x+=lowbit(x);
}}
intmain()
for(int i=1;i<=n;++i) e[i].id=i;
intp;
for(int k=1;k<=4;++k)
change(e[i].xy,e[i].x+e[i].y,e[i].id,m);
}
}sort(f+1,f+tot+1
,cmp2);
int now=0
,fu,fv;
for(int i=1;i<=n;++i) fa[i]=i;
long
long ans=0
;
for(int i=1;i<=tot;++i)
}printf(
"%lld
",ans);
}
二維曼哈頓最小生成樹
所以我們只要求乙個點在其45 角的區域內離他最近的點就行了,而這可以用線段樹或樹狀陣列解決 我們以y軸正半軸往右偏45 角的區域為例 點j在點i的這個區域要滿足的條件是 yj xj yi xi 且xj xi 那麼我們將點以x為第一關鍵字,y為第二關鍵字,排序後倒序插入線段樹 線段樹的線段這一維是離散...
曼哈頓距離最小生成樹
一 前人種樹 部落格 曼哈頓距離最小生成樹與莫隊演算法 部落格 學習總結 最小曼哈頓距離生成樹 二 知識梳理 曼哈頓距離 給定二維平面上的n個點,在兩點之間連邊的代價。即distance p1,p2 x1 x2 y1 y2 曼哈頓距離最小生成樹問題求什麼?求使所有點連通的最小代價。最小生成樹的 環切...
51nod1213 二維曼哈頓距離最小生成樹
二維平面上有n個座標為整數的點,點x1 y1同點x2 y2之間的距離為 橫縱座標的差的絕對值之和,即 abs x1 x2 abs y1 y2 也稱曼哈頓距離 求這n個點所組成的完全圖的最小生成樹的邊權之和。input 第1行 1個數n,表示點的數量。2 n 50000 第2 n 1行 每行2個數,表...