最短路 仙人掌圓方樹 LCA

2021-10-04 03:07:47 字數 2378 閱讀 5439

將原圖首先變成一棵樹,這裡就是對仙人掌進行圓方樹處理,於是接下去就是對新圖進行處理了。

比較簡單的,就是我們搜到的lca點是圓點,那麼肯定此時的距離就是答案了,如果不是圓點呢?此時的lca點是方點的話,那麼最後的最短距離還不好說,因為存在可能走環的另一頭更近的可能性,或者它二者的距離可以更近,這裡的話,就是特別處理一下即可,是通過環上原距離,還是環的另外半圈更近,分別進行考慮即可。

#include #include #include #include #include #include #include #include #include #include #include #include #include //#include //#include #define lowbit(x) ( x&(-x) )

#define pi 3.141592653589793

#define e 2.718281828459045

#define inf 0x3f3f3f3f3f3f3f3f

#define eps 1e-8

#define half (l + r)>>1

#define lsn rt<<1

#define rsn rt<<1|1

#define lson lsn, l, mid

#define rson rsn, mid+1, r

#define ql lson, ql, qr

#define qr rson, ql, qr

#define myself rt, l, r

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

#define max_3(a, b, c) max(a, max(b, c))

#define rabc(x) x > 0 ? x : -x

using namespace std;

typedef unsigned long long ull;

typedef unsigned int uit;

typedef long long ll;

const int maxn = 2e4 + 7, maxm = 1e5 + 7;

int n, m, q;

struct graph

} edge[maxm];

inline void addeddge(int u, int v, ll w)

inline void _add(int u, int v, ll w)

inline void clear()

} old, now;

int dfn[maxn], low[maxn], tot, stap[maxn], stop, bcnt;

ll dis[maxn], tlen[maxn], las[maxn];

bool instack[maxn] = , type[maxn];

vectorb_po[maxn];

inline void work(int u, int v)

while(p ^ v);

now._add(u, n + bcnt, 0);

}void tarjan(int u, int fa)

else if(low[v] == dfn[u])

low[u] = min(low[u], low[v]);

}else if(instack[v])}}

}int root[maxn][20], log_2[maxn], deep[maxn];

ll line[maxn][20];

void dfs(int u, int fa)

for(int i=now.head[u], v; ~i; i=now.edge[i].nex)

}ll lca(int u, int v)

}if(u == v) return ans;

for(int i=log_2[n + bcnt]; i>=0; i--)

}if(root[u][0] <= n)

ll tdis = tlen[root[u][0] - n];

if(type[u] == type[v])

else

return ans;

}inline void init()

log_2[i] = k;

}}int main()

dis[1] = 0;

tarjan(1, 0);

deep[0] = 0;

dfs(1, 0);

int u, v;

while(q --)

return 0;}/*

5 5 1

1 2 1

1 3 1

2 3 1

2 4 1

3 5 1

4 5*/

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

bzoj 求仙人掌上兩點間的最短路 終於要構建圓方樹啦 首先構建出圓方樹,因為是仙人掌,和一般圖可以稍微的不一樣 直接t arja n tar ja n縮點,對於每乙個強連通分量構建方點 只有乙個點的就不要建了 圓方邊的權值定義為到df s dfs tarjan t ar ja n不就是搞了一棵df...

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

給乙個n個點m條邊的連通無向圖,滿足每條邊最多屬於乙個環,有q組詢問,每次詢問兩點之間的最短路徑。建出圓方樹。對於圓圓邊,邊權為原仙人掌的邊權 對於圓方邊,邊權為圓點到方點代表的環中dfs序最小的點的距離。對於每個詢問,如果lca為圓點,那麼答案為兩點距離 如果是方點,答案為兩點到方點代表的環的距離...

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

bzoj 求仙人掌上兩點間的最短路 終於要構建圓方樹啦 首先構建出圓方樹,因為是仙人掌,和一般圖可以稍微的不一樣 直接 tarjan 縮點,對於每乙個強連通分量構建方點 只有乙個點的就不要建了 圓方邊的權值定義為到 dfs tarjan 不就是搞了一棵 dfs 樹出來嗎?樹上深度最小的點的最短距離。...