BZOJ2125 最短路 圓方樹 倍增LCA

2021-08-19 02:37:50 字數 2223 閱讀 4547

最短路

做法:本題需要用到圓方樹來處理仙人掌。

題目中所給的圖稱作仙人掌圖,即每條邊至多在乙個環上的圖。對於這種圖,我們一般把它轉化成樹後,將樹上的某些演算法修改後來解決仙人掌上的問題。常用的一種轉化方式就是圓方樹。

在圓方樹中,乙個圓點表示原仙人掌中就有的點,而乙個方點表示乙個點雙連通分量(環),並且乙個方點和它表示的環中所有的點連邊。那麼我們怎麼樣構造出圓方樹呢?在求點雙連通分量的tarjan演算法中稍作修改,因為乙個環上的點在棧中的順序和它們在原仙人掌上的順序是一樣的,所以還可以順便求出環上的一些資訊。要注意的是,如果乙個點雙中只有乙個點,一般不再對這個點建方點。

回到這一題,我們知道樹上的最短路用倍增lca求出即可,轉移到仙人掌上,首先要考慮邊權的設定。我們自頂向下來看,如果是圓方邊,那麼邊權就是

0 0

,如果是方圓邊,那麼邊權就是從圓點到方點表示的點雙的根(即在圓方樹中深度最淺的點)的最短路長度。對於每個環維護環長,再對於每個點維護從它所在的點雙(這裡指根不為它本身的那個點雙)的根到它的最短路是從哪一側走過來的。接下來我們分類討論:

1.如果兩個點的lca是圓點,那麼它們之間的最短路顯然就是路徑上的邊權和了。

2.如果兩個點的lca是方點,那麼它們會往上跳到兩個圓點,這兩個圓點在同乙個環上,因此我們要計算這兩個點在環上的最短路。根據從根到這兩個點的最短路是不是從同一側來的分類討論即可。

整個演算法時間複雜度是o(

nlog⁡n

)' role="presentation" style="position: relative;">o(n

logn)o

(nlog⁡n)

,可以通過此題。

以下是本人**:

#include 

using

namespace

std;

typedef

long

long ll;

int n,m,q,first[10010]=,tot=0,firsted[20010]=;

int totpbc,st[10010]=,low[10010],dfn[10010],tim=0,top=0;

ll dis[10010]=,last[10010],len[20010],sum[20010][20]=;

int fa[20010][20]=,dep[20010]=;

bool vis[10010]=,inst[10010]=,type[10010]=;

struct edge

e[100010],ed[200010];

void insert(int a,int b,ll w,int id)

void inserted(int a,int b,ll w)

void combine(int v,int now)

else inserted(st[top],totpbc,0);

}}void tarjan(int v,int laste)

else

if (low[e[i].v]==dfn[v]) combine(v,now);

low[v]=min(low[v],low[e[i].v]);

}else

if (inst[e[i].v])

}}void dfs(int v)

}void solve(int a,int b)

if (a==b)

for(int i=15;i>=0;i--)

if (fa[a][i]!=fa[b][i])

if (fa[a][0]<=n)

int rt=fa[a][0];

ll a=sum[a][0],b=sum[b][0],mn;

if (type[a]==type[b]) mn=min(abs(a-b),len[rt]-abs(a-b));

else mn=min(a+b,len[rt]-a-b);

printf("%lld\n",ans+mn);

}int main()

totpbc=n;

tot=0;

tarjan(1,0);

dep[0]=-1;

dfs(1);

for(int i=1;i<=15;i++)

for(int j=1;j<=totpbc;j++)

for(int i=1;i<=q;i++)

return

0;}

BZOJ2125 最短路 圓方樹

思路 關於靜態仙人掌的問題,建立出圓方樹比較好求解。求出來之後處理每個圓點方點的情況,原來的是樹邊直接處理,環邊的話方點連向環上每個圓點一條邊,權值為每個節點到環的父親節點的最短距離。然後倍增預處理,查詢的時候,如果lc a lca 是圓點直接輸出,否則兩個點是環上的點,處理他們在環上的最短距離即可...

bzoj2125 圓方樹 最短路

description 給乙個n個點m條邊的連通無向圖,滿足每條邊最多屬於乙個環,有q組詢問,每次詢問兩點之間的最短路徑。input 輸入的第一行包含三個整數,分別表示n和m和q 下接m行,每行三個整數v,u,w表示一條無向邊v u,長度為w 最後q行,每行兩個整數v,u表示一組詢問 output ...

BZOJ2125最短路 初識圓方樹

sto sto sto yyb orz orz orz bzoj2125 非許可權 不知道圓方樹應該歸在資料結構還是圖論,先放在這裡,圓方樹,對於狹義圓方樹,可以解決一類仙人掌的問題。對於仙人掌的定義,通俗來講就是對於乙個無向圖每一條邊有且僅僅被乙個環所包含 最後看起來就像是乙個乙個環圈圈,最終ju...