為了降低ac率
這道題目我各種花樣作死爆oj,最後還是和標算改得差不多了。。。
顯然答案應該為建築物構成的最小生成樹中,兩點間的最大路徑;那麼只要得到這棵最小生成樹就可以用倍增在o(qlogn)的時間內得到答案了。因此關鍵是求最小生成樹。
注意到是平面圖,因此考慮用bfs求最小生成樹。直接以每個建築為原點拓展顯然不行,那麼我們可以把每個建築都加入佇列一起拓展,那麼對於乙個點,一定會被其中的乙個建築第一次拓展到,則令這個點為該建築的「勢力範圍」。那麼對於兩個建築「勢力範圍」邊界上接觸的點,顯然這兩個建築之間的邊只能有邊界上的點得到。因此就用這些點連邊即可。顯然這樣得到是最小生成樹。
然後用倍增求lca的方法得到答案即可。
ac**如下:
#include#include#include#define n 2005
#define m 200005
using namespace std;
int n,m,pt,cas,tot,cnt,fa[m][18],g[m][18],bin[25],anc[m],fst[m],pnt[n*n],nxt[n*n],len[n*n];
int dep[m],h[n*n][2],d[n][n],blg[n][n]; bool mp[n][n];
const int dx[4]=,dy[4]=;
int read()
return x;
}struct grapg
}g1,g2;
int getanc(int x)
void dfs(int x)
for (p=g2.fst[x]; p; p=nxt[p]) }}
int qry(int x,int y)
if (x!=y) ans=max(ans,max(g[x][0],g[y][0])); return ans;
}int main()
int head=0,tail=0,x,y,z;
memset(d,-1,sizeof(d));
for (i=1; i<=pt; i++)
while (head0 && u<=m && v>0 && v<=n && mp[u][v])
if (d[u][v]==-1) else if (z!=blg[u][v]) g1.add(d[u][v]+d[x][y],z,blg[u][v]);
} }for (i=0; i
by lych
2016.3.26
題目 BZOJ 4242 水壺
題目大意 某市是乙個被分成h w h times w h w塊區域的長方形,每個區域都是建築物 原野 牆壁之一。建築物的區域有p pp個,編號為1 p 1 dots p 1 p。只有建築物和原野能夠進入,而且每次只能走到相鄰的區域中,且不能移動到市外。現在需要在各個建築物之間往返。在原野上每走過乙個...
bzoj 2561 最小生成樹
給定乙個邊帶正權的連通無向圖g v,e 其中n v m e n個點從1到n依次編號,給定三個正整數u,v,和l u v 假設現在加入一條邊權為l的邊 u,v 那麼需要刪掉最少多少條邊,才能夠使得這條邊既可能出現在最小生成樹上,也可能出現在最大生成樹上?第一行包含用空格隔開的兩個整數,分別為n和m 接...
bzoj2561 最小生成樹
time limit 10 sec memory limit 128 mb submit 1024 solved 520 submit status discuss 給定乙個邊帶正權的連通無向圖g v,e 其中n v m e n個點從1到n依次編號,給定三個正整數u,v,和l u v 假設現在加入一...