>description
這是一道靜態仙人掌(block forest data structure)的模板題。
如果您不知道什麼是仙人掌,那麼此處給出無向仙人掌圖的定義:
任意一條邊至多只出現在一條簡單迴路的無向連通圖稱為仙人掌。
給你乙個有 n 個點和 m 條邊的仙人掌圖,和 q 組詢問
每次詢問兩個點 u,v求兩點之間的最短路。
>input
第一行三個正整數 n,m,q,意義如題目描述。
接下來 mmm 行,每行三個正整數 u,v,w,表示 u,v 之間有一條權值為 w 的無向邊。
然後 q 行,每行兩個正整數 u,v,詢問 u 到 v 的最短路。
>output
q 行,每行乙個正整數,對應一次詢問的結果。
>解題思路
(我講的不太好,具體看碼吧==)
樣例的圖是這樣的:
我們要對仙人掌建乙個圓方樹,在每乙個環中間建乙個方點,刪掉環上的路徑,把環上的所有點都連向方點,邊權為其中各個點到dfs序最小的點的最短路
如何找環?(tarjan演算法 )
這裡有兩個陣列:dfn
[i]dfn[i]
dfn[i]
第i點的dfs序,low
[i]low[i]
low[i]
第i點所在的子樹(往下走)可以走到的最小的dfs序
l ow
lowlo
w的作用可以這樣想,如果對於乙個普通的點,low[i]一定為dfn[i],但是對於在環上的乙個點,low[i]就為這個環上dfs序最小的那個點
用樹遞迴下去,如果遇到了環就終止遞迴,判斷環:乙個點i直接相連的乙個點j,如果j的dfs序大於i,並且j的父親不是i,那麼這就是乙個環,並且i是這個環中dfs序最小的,可以進行建環
建出類似下圖這樣的一棵圓方樹:
最後求距離,因為這是一棵樹,所以我們可以用lca求最短路,
有兩種情況:
lca是圓點,直接計算距離就行了
lca是方點,我們要記憶x和y求lca的最後一步x和y,他們的lca是x和y一起往上跳一步,所以x和y一定是兩個圓點,且在同乙個環中,我們的答案要加上x和y之間的最短路(這裡預處理sum)
>**
#include
#include
#include
#define n
200005
#define int long long
using namespace std;
struct line
a[400005
], aa[
400005];
int n, m, q, t, h[n]
, tt, hh[n]
, dfn[n]
, low[n]
, w, fa[n]
, k[n]
, cnt;
int sum[n]
, dep[n]
, lg[n]
, f[n]
[50], dis[n]
,x,y
;int read()
return l;
}void
write
(int l
)void
add(
int u, int v, int l
); h[u]
= t;
a[++t]
=(line)
; h[v]
= t;
}//建原圖
void
addd
(int u, int v, int l
); hh[u]
= tt;
aa[++tt]
=(line)
; hh[v]
= tt;
}//建圓方圖
void
build
(int u, int v, int l)
//建方點
sum[cnt]
= sum[u]
; x = v;
while
(x != fa[u])}
void
tarjan
(int now)
//tarjan找環
else low[now]
=min
(low[now]
, dfn[a[i]
.to]);
//環的情況,同樣更新low
if(low[a[i]
.to]
> dfn[now]
)addd
(now, a[i]
.to, a[i]
.c);
//圓方樹加入正常的邊
}for
(int i = h[now]
; i; i = a[i]
.next)
if(dfn[a[i]
.to]
> dfn[now]
&& now != fa[a[i]
.to]
)//找環
build
(now, a[i]
.to, a[i]
.c);
}void
dfs(
int now, int fath)}
int lca
(int x, int y
)//求lca
signed main()
tarjan(1
);memset
(dis,
0x7f
,sizeof
(dis));
dis[1]
=0;for
(int i =
1; i <= n; i++
) lg[i]
= lg[i -1]
+(1<< lg[i -1]
== i)
;//log預處理
dfs(1,
0);
int x, y, z, ans =0;
for(int i =
1; i <= q; i++
)write
(ans)
;putchar(10
);}return0;
}
清華集訓2015 靜態仙人掌 仙人掌剖分
毒瘤仙人掌,明明放到樹上一道板題的非要構造到仙人掌上來出題orz orz orz orz orz 在oi的上古時代,流傳著這樣乙個故事 有一天,小w到森林裡遊玩,回來之後跟小v說,我發現好多棵會動的樹耶!小v說,這有什麼好稀奇的,我用手指頭就能維護每棵樹的形態。於是又過了幾天小w到沙漠裡遊玩,回來之...
動態仙人掌(dinosaur
分析 這道題在考場看到我是完全的蒙蔽的,驚人的妄想著能否用資料離散化後的dp來騙分。我果然很菜。好吧,對於我這種菜雞來說,正解似乎有些難想,讓我們考慮從最基本的情況開始考慮。先將所有仙人掌按p為第一關鍵字排序,從左向右掃。這裡我們考慮乙個貪心策略,如果仙人掌兩兩之間距離足夠遠,則仙人掌之間跳躍的最小...
題解 仙人掌計數
題目傳送門 給出 q 個查詢,每次查詢 n 個點的無根有標號仙人掌有多少個。q le 5 times 10 4,n 131072 因為這道題太難碼了,所以先把題解寫了再寫 好奇怪啊 終於碼出來了,果然還是 text 好用 霧 為了方便,我們下面的答案其實求的是有根有標號的答案,最後除以 n 就好了。...