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

2021-06-05 04:05:39 字數 1754 閱讀 3806

這些天一直在集訓,考了十幾次……

zzy出了一道曼哈頓距離下的最小生成樹,考場上我沒做出來……

嗯……這種題目的問題在於,你沒辦法把每兩個點都建一條邊……

但是因為是曼哈頓距離,所以有一些特殊性質

容易證明,將某個點為原點建立笛卡爾座標系,將座標系分為每45°角為一塊的八個區域

那麼這個點向每個區域只會朝其中的某個點連邊……

為什麼說容易證明,因為我不會證……網上ms有這種證明的說……

貼一下zzy的題解:

所以我們只要求乙個點在其45°角的區域內離他最近的點就行了,而這可以用線段樹或樹狀陣列解決

我們以y軸正半軸往右偏45°角的區域為例:

點j在點i的這個區域要滿足的條件是:

yj-xj>yi-xi

且xj>xi

那麼我們將點以x為第一關鍵字,y為第二關鍵字,排序後倒序插入線段樹

線段樹的線段這一維是離散後的y-x,值是y+x

我們要求的是大於yi-xi的最小的y+x,而xj>xi這個條件已經由插入順序滿足了

這樣我們成功的解決了這個區域的點

而其他區域的點我們可以通過座標變換轉移到這個區域

由於對稱性,我們注意到其實只要求x軸或y軸正半軸所在的四個區域就行了

那麼這個問題就這樣解決了

不過,我沒有找到地方提交這個題目……只是ac了zzy的題

**在此:題目是求最小生成樹上第k大邊,使用了樹狀陣列

//lib

#include#include#include#include#include#include#include#include#include#include#include#include#includeusing namespace std;

//macro

#define rep(i,a,b) for(int i=a,tt=b;i<=tt;++i)

#define drep(i,a,b) for(int i=a,tt=b;i>=tt;--i)

#define erep(i,e,x) for(int i=x;i;i=e[i].next)

#define irep(i,x) for(typeof(x.begin()) i=x.begin();i!=x.end();i++)

#define read() (strtol(ipos,&ipos,10))

#define sqr(x) ((x)*(x))

#define pb push_back

#define ps system("pause");

typedef long long ll;

typedef pairpii;

const int oo=~0u>>1;

const double inf=1e100;

const double eps=1e-6;

string name="brs", in=".in", out=".out";

//var

int n,k,cnt,tot,ans;

int lisan[100008],l[100008];

int limit=1000000008;

struct p

int query(int x)

{ int ret=oo,pos=n+1;

for(int i=x;i<=n;i+=lowbit(i))

if(s[i]

這個程式效率巨低,開o2和不開o2差距達到1倍以上……雖然我覺得這種寫法很優美就是了……

曼哈頓距離最小生成樹

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

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

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

二維曼哈頓距離最小生成樹

原理 每個點在以它為頂點的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...