link:最短路
一張仙人掌圖 求圖中兩點最短路。
\(n<=10000,q<=10000,w>=1\)
考慮邊數是多少 m>=n-1 對於一張仙人掌圖 考慮先構建出來dfs樹 非樹邊會形成環 環不可能相交 也沒有自環 那麼說一每形成乙個環需要一條樹邊和非樹邊。
所以m<=2n-2.
求圖中兩點最短路。離線做也不太好做。考慮一下乙個點到另外乙個點 會經過一些割點 必經之點 那麼任意兩個割點之間的最短路有兩條。
顯然其中一條永遠沒用 考慮構建出圓方樹 邊權dfs的時候處理一下即可。求距離樹上求lca即可。
不知道**掛了 回來再調。
4.6 update:閒來無事拍了一下 發現了自己的思想漏洞。
之前少處理了一種情況 考慮乙個環內 兩點各自的兒子之間的最短距離。
他們的lca為方點 這說明了要爬到這個環內然後然後 對於環有兩條路徑 所以需要特判 我之前只注意到環內點了 所以掛了。
正確的是 判lca 然後x向上跳 y向上跳 然後計算距離即可。
計算環的距離時我暴力了一點 求了一發 l 和 r陣列.
const int maxn=20010;
int n,m,q,len=1,cnt,top,sum,len1,id,cc;
int dfn[maxn],low[maxn],s[maxn],f[maxn][20],a[maxn],b[maxn],log[maxn],l[maxn],r[maxn];
int lin[maxn],ver[maxn<<1],nex[maxn<<1],e[maxn<<1],d[maxn],dis[maxn],w[maxn],h[maxn];
int lin1[maxn],ver1[maxn<<1],nex1[maxn<<1],e1[maxn<<1];
inline void add(int x,int y,int z)
inline void add1(int x,int y,int z)
inline void solve(int x)
++id;solve(x);}}
else
}}inline void dfs(int x,int fa)
}inline int lca(int x,int y)
inline int get_x(int x,int w)
int main()
id=n;dfs(1);
rep(2,id,i)log[i]=log[i>>1]+1;
dfs(1,0);
rep(1,q,i)
put(dis[x]+dis[y]-dis[lca]*2);
}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...