2015-04-29 21:58:58
題目:題意有先爭議... 其實出題人就是想考:求曼哈頓距離最小生成樹上的第k大的邊。
關於 manhattan mst 的介紹:部落格。
然後就是比較裸的問題了... 最後用kruskal找第k大的邊。
過程基本上可以簡述為:
(1)將所有點經歷四種變換【不變,y=x對稱,y=0對稱,y=x對稱】
(2)對於每種變換,要找出每個點在 y 軸向右45度的1/8象限區域內最近的點。
首先對所有點按 x 排序,再把 y- x離散化(若資料大),然後對於每個點用樹狀陣列求出 y-x 比該點大且 x+y 最小的點,兩點建邊。
(3)根據建的邊跑一遍kruskal,找第 n-k 條邊即可。
#include #include#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using
namespace
std;
#define mem(a,b) memset(a,b,sizeof(a))
#define rep(i,n) for(int i=0;i<(n);++i)
#define for(i,a,b) for(int i=(a);i<=(b);++i)
#define getmid(l,r) ((l) + ((r) - (l)) / 2)
#define mp(a,b) make_pair(a,b)
#define pb(a) push_back(a)typedef
long
long
ll;typedef pair
pii;
const
double eps = 1e-8
;const
int inf = (1
<< 30) - 1
;const
int maxn = 10010
;int
n,k;
intfa[maxn],a[maxn],b[maxn];
intecnt;
struct
edge
}e[4 *maxn];
void add_edge(int u,int v,int
c)struct
node
}p[maxn];
struct
bit
int lowbit(int x)
void update(int x,int d,int
pos)
x -=lowbit(x);}}
intget(int
x) x +=lowbit(x);
}return
pos;
}}bit;
int dis(int a,int b)
int find(int x)
intmanhattan_mst()
}//kruskal
sort(e + 1,e + ecnt + 1
);
int cnt = n -k;
for(i,
1,n) fa[i] =i;
for(i,
1,ecnt)
}}int
main()
ecnt = 0
; printf(
"%d\n
",manhattan_mst());
}return0;
}
關於曼哈頓距離的最小生成樹 POJ3241
題目位址 題目就是給你n個點 求n個點的曼哈頓距離的最小生成樹 輸出所有邊中第k大的的邊的權重。n個點那麼有有n n 1 條邊如果採用樸素的prim演算法建邊就是o n2 的複雜度,我們來考慮一下曼哈頓距離的特殊性,其實不是所有的邊都需要,在建邊的時候就可以去掉很多多餘的邊。如圖,對於給定的一些點我...
poj3241 曼哈頓最小生成樹
題意 求曼哈頓距離最小生成樹第k大的邊。曼哈頓距離 點a x1,y1 與點b x2,y2 距離d abs x1 x2 abs y1 y2 求解曼哈頓距離最小生成樹的方法簡述 如果直接兩兩點建邊,總邊數則為o n2 條,用時間複雜度o n e 的prim演算法,時間複雜度o e loge 的krusk...
poj 2926 最大曼哈頓距離
題目大意 給你 個數的五維座標,要你求任意兩點之間的最大曼哈頓距離 思路 對於點i和j 曼哈頓距離為 x1 x2 y1 y2 去掉絕對值 x1 y1 x2 y2 且對應的位置加減符號相同 那麼對於五維座標就有2 5種可能 然後列舉求出最大值 include include define inf 0x...