poj3241 曼哈頓最小生成樹

2022-08-15 05:12:14 字數 4028 閱讀 2431

題意:求曼哈頓距離最小生成樹第k大的邊。曼哈頓距離:點a(x1,y1)與點b(x2,y2)距離d=abs(x1-x2)+abs(y1-y2)。

求解曼哈頓距離最小生成樹的方法簡述:

如果直接兩兩點建邊,總邊數則為o(n2)條,用時間複雜度o(n+e)的prim演算法,時間複雜度o(e*loge)的kruskal演算法都是會超時的(這裡n為點數,e為邊數)

而這裡的解題思路就是將邊數複雜度降到o(n),因為大量的邊是沒有用到的,只要每45度方向距離該點最近的乙個點連邊即可。

證明就不證了,直接上結論,假如b,c都是a 在y

'>y

軸向右45度區域內並且 

依據上面可得只要連線每個點與八個方向距離最小的點連邊即可。

又因為,邊是雙向的,我們只要連r1,r2,r3,r4四個方向即可。比如:(上圖)b是a r1最小距離點,a是b r5最小距離點,我們只要連r1,r5不連,即a連向b即可知道ab的關係。

思路出來了,那麼怎麼處理呢?我們先考慮乙個方向,例如r1,(其他三個方向模擬即可)。

在某個點a(x

0,y0

)'>a(x0,y0)

的這個區域內的點b(x

1,y1

)'>b(x1,y1)

滿足x1≥x

0'>x1≥x0 且y1

−x1>y0

−x0'>y1−x1>y0−x0

。那麼b就在a的r1上|ab

|=y1

−y0+

x1−x

0=(x

1+y1

)−(x

0+y0

)'>。a(

x0,y

0)'>b(x

1,y1

)'>x1≥

x0'>y1−

x1>y0

−x0'>|ab

|=y1

−y0+

x1−x

0=(x

1+y1

)−(x

0+y0

)'>在a

'>a

的r1區域內距離a

'>a

最近的點也即滿足條件的點中x+y

'>x+y

最小的點。因此我們可以將所有點按x

'>x

座標排序,再按y−x

'>y−x

離散。a(x

0,y0

)'>b(x

1,y1

)'>x1≥

x0'>y1−

x1>y0

−x0'>|ab

|=y1

−y0+

x1−x

0=(x

1+y1

)−(x

0+y0

)'>a

'>a

'>x+y

'>x

'>y−x

'>用線段樹或者樹狀陣列維護大於當前點的y−x

'>y−x

的最小的x+y

'>x+y

對應的點(也就是維護區間最小值)這裡用的是樹狀陣列,因為**較簡單。a(

x0,y

0)'>b(x

1,y1

)'>x1≥

x0'>y1−

x1>y0

−x0'>|ab

|=y1

−y0+

x1−x

0=(x

1+y1

)−(x

0+y0

)'>a

'>a

'>x+y

'>x

'>y−x

'>y−x

'>x+y

'>樹狀陣列知識:

x0,y

0)'>b(x

1,y1

)'>x1≥

x0'>y1−

x1>y0

−x0'>|ab

|=y1

−y0+

x1−x

0=(x

1+y1

)−(x

0+y0

)'>a

'>a

'>x+y

'>x

'>y−x

'>y−x

'>x+y

'>這樣r1區域就處理完了,而其他三個區域的點只要用數學知識 翻轉和對稱 轉化成r1處理即可。比如,r2區域將關於y=x對稱(即swap(x,y)),再將關於a(

x0,y

0)'>b(x

1,y1

)'>x1≥

x0'>y1−

x1>y0

−x0'>|ab

|=y1

−y0+

x1−x

0=(x

1+y1

)−(x

0+y0

)'>a

'>a

'>x+y

'>x

'>y−x

'>y−x

'>x+y

'>x軸對稱(即x=-x)可求r3,再關於y=x對稱求r4。a(

x0,y

0)'>b(x

1,y1

)'>x1≥

x0'>y1−

x1>y0

−x0'>|ab

|=y1

−y0+

x1−x

0=(x

1+y1

)−(x

0+y0

)'>a

'>a

'>x+y

'>x

'>y−x

'>y−x

'>x+y

'>還有些細節可以看**:a(

x0,y

0)'>b(x

1,y1

)'>x1≥

x0'>y1−

x1>y0

−x0'>|ab

|=y1

−y0+

x1−x

0=(x

1+y1

)−(x

0+y0

)'>a

'>a

'>x+y

'>x

'>y−x

'>y−x

'>x+y

'>**:

#include#include

#include

#include

#include

#include

#define inf 0x3f3f3f3f

using

namespace

std;

typedef

long

long

ll;const

int maxn=1e5;

struct

point

}p[maxn];

//按x從小到大排序,再按y-x離散

struct

node

}edge[maxn

<<3

];struct bit

}bit[maxn];

int fa[maxn],a[maxn],b[maxn];//

陣列a,b用於離散化,求得 在y軸向右45度的所有點

intn,m,k,cnt;

int find(int

x)void add(int u,int v,int

w)int lowbit(int x)

int dist(point a,point b)

int query(int x,int m)

}return

pos;

}void update(int x,int y,int pos)

}}void solve()

if(tot==k)

}}void

caledge()

}int

main()

solve();

return0;

}

關於曼哈頓距離的最小生成樹 POJ3241

題目位址 題目就是給你n個點 求n個點的曼哈頓距離的最小生成樹 輸出所有邊中第k大的的邊的權重。n個點那麼有有n n 1 條邊如果採用樸素的prim演算法建邊就是o n2 的複雜度,我們來考慮一下曼哈頓距離的特殊性,其實不是所有的邊都需要,在建邊的時候就可以去掉很多多餘的邊。如圖,對於給定的一些點我...

POJ 3241(曼哈頓距離,MST)

2015 04 29 21 58 58 題目 題意有先爭議.其實出題人就是想考 求曼哈頓距離最小生成樹上的第k大的邊。關於 manhattan mst 的介紹 部落格。然後就是比較裸的問題了.最後用kruskal找第k大的邊。過程基本上可以簡述為 1 將所有點經歷四種變換 不變,y x對稱,y 0對...

曼哈頓距離最小生成樹

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