將原圖首先變成一棵樹,這裡就是對仙人掌進行圓方樹處理,於是接下去就是對新圖進行處理了。
比較簡單的,就是我們搜到的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 樹出來嗎?樹上深度最小的點的最短距離。...