題目位址
題目就是給你n個點 求n個點的曼哈頓距離的最小生成樹 輸出所有邊中第k大的的邊的權重。
n個點那麼有有n∗
(n−1
) 條邊如果採用樸素的prim演算法建邊就是o(
n2) 的複雜度,我們來考慮一下曼哈頓距離的特殊性,其實不是所有的邊都需要,在建邊的時候就可以去掉很多多餘的邊。
如圖,對於給定的一些點我們選取乙個點那麼可以以這個點為原點建立乙個直角座標系,然後把每乙個象限劃分為兩個區域,對於每乙個區域我們的單獨考慮,例如我們來考慮r1區域,有a,b兩個點原點是o,那麼如果o點要向這個區域內的點連邊,最多只能建一條邊。這是為什麼呢?
首先來看如果能夠建兩條或者以上的邊,比如oa和ob那麼,oab構成乙個三角形,角aob小於60度,角oab大於90度,那麼ob一定是三角形的最長邊,也就是做|ob|>|ab|,也就是說,我選擇建立oa和ab這兩條邊是比oa和ob這兩條邊要更優的。所以只會連一條邊。
然後問題就變成了在r1區域內找一條距離o最短的點建邊就可以了,我們設 o(
x0,y
0),a
(x1,
y1) 那麼a點滿足y1
−y0>x1
−x0,
x1>x0
移項得 y1
−x1>y0
−x0,
x1>x0
,這時候的曼哈頓a與o的曼哈頓距離表示為(y
1−y0
)+(x
1−x0
)⇒(y
1+x1
)−(x
0+y0
) ,也就是求滿足y1
−x1>y0
−x0,
x1>x0
的最小的y1
+x1 。
這裡可以用樹狀陣列來離散y-x*(乙個能夠查詢區間x到上限最值得樹狀陣列),就可以在o(
nlog
n)複雜度內求出可能的邊。
具體做法:
首先將所有的點按照x從小到大排列好,然後把每個點的y-x算出來的複製兩份分別存到兩個陣列a1,a2當中,把a2排序後去除相同的數。
然後從大到小遍歷每個點,在當前點的時候,a1中y-x和當前點是對應的,這個時候二分從a2中找到這個y-x的排名,也就是這個點的y-x大小排在第幾位,假如是第pos位,那麼我們在樹狀陣列當中找pos到最大區間的範圍內的最小x+y的點的編號,然後當前點和這個點建邊(大家到這裡可能有點懵,為什麼能找到?我們繼續往下看)然後把當前點的x+y的值插入到陣列當中pos位置,其實大家應該就能理解為什麼能查到了,應為我們是插入到pos的位置 那麼對於一起的比當前y-x要大的點肯定是插入到pos的後面的位置的,也就是說pos後面的位置全部是y-x比當前還要大的點,那麼區間查詢的時候也就滿足了這個區間所有的y-x比當前的要大,然後存的時候x+y,所以是找乙個這個區間的最小值(注意記錄點的編號)。
然後對於其他的區間r2…其實根據對稱性 我們只需要找列舉四個區間就可以了,應為另外四個剛好相反,是重複的。這裡我們列舉r1,r2,r3,r4。其實每個區間可以根據變換把它移動到r1區間,例如要列舉r2,可以把所有的點繞y=x翻轉一下,就是交換所有點的y和x,然後其他區間同理,可以變換過來。
這樣我們就得到了所有可能的邊,然後用kruskal演算法在可能的邊中找出最小樹的邊。
**:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define clr(x) memset(x,0,sizeof(x))
#define clm(x) memset(x,0x3f,sizeof(x))
using
namespace
std;
#define ll long long
const
int n = 100005;
struct bit
inline
int lowbit(int k)
void update(int pos,int val,int id)
pos-=lowbit(pos);}}
int read(int pos,int m)
pos += lowbit(pos);
}return ans;
}}b;struct pos
b.update(pos,p[i].x+p[i].y,i);
}}int fa[n],k;
int _find(int x)
void manhattan(int n)
}}int main()
manhattan(n);
sort(ansedg,ansedg+acnt);
printf("%d\n",ansedg[acnt-k].d);
}return
0;}
曼哈頓距離最小生成樹
一 前人種樹 部落格 曼哈頓距離最小生成樹與莫隊演算法 部落格 學習總結 最小曼哈頓距離生成樹 二 知識梳理 曼哈頓距離 給定二維平面上的n個點,在兩點之間連邊的代價。即distance p1,p2 x1 x2 y1 y2 曼哈頓距離最小生成樹問題求什麼?求使所有點連通的最小代價。最小生成樹的 環切...
關於曼哈頓距離下的最小生成樹
這些天一直在集訓,考了十幾次 zzy出了一道曼哈頓距離下的最小生成樹,考場上我沒做出來 嗯 這種題目的問題在於,你沒辦法把每兩個點都建一條邊 但是因為是曼哈頓距離,所以有一些特殊性質 容易證明,將某個點為原點建立笛卡爾座標系,將座標系分為每45 角為一塊的八個區域 那麼這個點向每個區域只會朝其中的某...
二維曼哈頓距離最小生成樹
原理 每個點在以它為頂點的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 y...