BZOJ2125 最短路(仙人掌,圓方樹)

2021-08-21 22:32:10 字數 2518 閱讀 6650

給乙個n個點m條邊的連通無向圖,滿足每條邊最多屬於乙個環,有q組詢問,每次詢問兩點之間的最短路徑。

建出圓方樹。對於圓圓邊,邊權為原仙人掌的邊權;對於圓方邊,邊權為圓點到方點代表的環中dfs序最小的點的距離

對於每個詢問,如果lca為圓點,那麼答案為兩點距離;如果是方點,答案為兩點到方點代表的環的距離和加上兩點走到環上後所在的點的最短距離。

/**************************************

* au: hany01

* prob: bzoj2125 最短路(圓方樹)

* date: jul 30th, 2018

* email: [email protected]

**************************************/

#include

using

namespace

std;

typedef

long

long ll;

typedef pair pii;

typedef

vector

vi;

#define file(a) freopen(a".in", "r", stdin), freopen(a".out", "w", stdout)

#define rep(i, j) for (register int i = 0, i##_end_ = j; i < i##_end_; ++ i)

#define for(i, j ,k) for (register int i = (j), i##_end_ = (k); i <= i##_end_; ++ i)

#define fordown(i, j, k) for (register int i = (j), i##_end_ = (k); i >= i##_end_; -- i)

#define set(a, b) memset(a, b, sizeof(a))

#define cpy(a, b) memcpy(a, b, sizeof(a))

#define sz(a) ((int)(a.size()))

#define all(a) a.beg1in(), a.end()

#define pb(a) push_back(a)

#define mp(a, b) make_pair(a, b)

#define x first

#define y second

#define inf (0x3f3f3f3f)

#define inf1 (2139062143)

#define y1 wozenmezhemecaia

#ifdef hany01

#define debug(...) fprintf(stderr, __va_args__)

#else

#define debug(...)

#endif

template

inline

bool chkmax(t &a, t b)

template

inline

bool chkmin(t &a, t b)

inline

int read()

const

int maxn = 1e4 + 5, maxm = maxn << 2;

int n, e1 = 1, e2 = 1, beg1[maxn], nex1[maxm], v1[maxm], w1[maxm], beg2[maxn << 1], nex2[maxm], v2[maxm], dep[maxn << 1], fa1[maxn], fa2[15][maxn << 1], dfn[maxn], low[maxn], clk, tot;

ll dis1[maxn], dis2[maxn << 1], w2[maxm], cir[maxn];

inline

void add1(int uu, int vv, int ww)

inline

void add2(int uu, int vv, ll ww)

inline

void build(int u, int anc, ll dsum)

void dfs(int u, int fe)

for (register

int i = beg1[u]; i; i = nex1[i])

if (fa1[v1[i]] != u && dfn[v1[i]] > dfn[u]) build(v1[i], u, w1[i] + dis1[v1[i]] - dis1[u]);

}void dfs(int u)

inline

int lca(int u, int v)

inline

int climb(int u, int anc)

inline ll dist(int u, int v)

int main()

return

0;}

BZOJ2125 仙人掌 最短路

題意 求仙人掌上的多元最短路 考慮如果在樹上,u,v兩點之間的最短路為dis u dis v 2 dis lca 因為仙人掌每個點只屬於乙個簡單環,先dfs弄清仙人掌的結構,對於環把環中離根節點最近的點作為父親,環中其他點向這個點連邊,這樣就建出一棵新的樹,如果u,v的lca不在環上,就按照樹的做法...

BZOJ2125 仙人掌 最短路

bzoj2125 建出圓方樹,圓方邊的權值為圓點到環上最高點在dfs樹上的點的距離,這樣就可以記錄下環上兩個點的距離 並在方點處記錄一下環的總長,因為環上兩點間有兩條路徑可走,要分類討論 然後就是樹上求dis的問題,先求lca 然後lca如果是圓點就直接求距離 如果是方點就分類討論一下就好了 cod...

仙人掌最短路 BZOJ 2125 最短路

題解 首先如果這是一棵樹的話,那麼我們只需要選定乙個根,之後掃一遍這棵樹,詢問的話即是兩點到根節點的距離之和減去二倍的兩點lca到根節點距離。那麼如果是一棵仙人掌的話,我們強行套用這個辦法,重新構造一棵樹。對於仙人掌中的乙個環來說,我們把該環中深度最小的點當做這個環的根,然後環上其他點連向該環,非環...