bzoj3694 最短路 樹鏈剖分 線段樹

2022-05-01 22:36:18 字數 2150 閱讀 2586

最短路 bzoj-3694

題目大意:給你乙個n個點m條邊的無向圖,源點為1,並且以點1為根給出最短路樹。求對於2到n的每個點i,求最短路,要求不經過給出的最短路樹上的1到i的路徑上的最後一條邊。

注釋:$1\le n \le 4000$,$1\le m\le 10^5$。

想法:對於任意兩個點uv,滿足u和v之間直接相連了一條不在給出最短路樹上的邊,我們設這條邊的長度為val(u,v)。對於任意的乙個點i,它到根節點的最短路,也就是從根節點開始走最短路樹所到達i的路徑和,我們設為dis[i]。那麼,對於u到lca(u,v)之間的任意乙個點x,我們都可以從1(root)$\rightarrow$t$\rightarrow$v$\rightarrow$u$\rightarrow$x。我們可以用這條路徑更新x的答案。這條路徑的長度是dis[v]+val(u,v)+dis[u]-dix(x)。我們只需要令這樣的(dis[v]+val(u,v)-dis[u])即可。顯然,每兩個這樣滿足條件的u和v,都可以更新從u到lca(u,v)之間的點和v到lca(u,v)之間的點,就是區間取min。這個操作我們可以用樹鏈剖分+線段樹實現。

最後,附上醜陋的**... ...

#include#include#include#include#include#include#define ll long long

#define inf 1000000000

using namespace std;

inline ll read()

while(ch>='0'&&ch<='9')

return x*f;

}int n,m,cnt1,cnt2=1,place;

int bin[12];

int u[100005],v[100005],w[100005];

int dis[100005],deep[100005],son[100005],fa[100005][12];

int pl[100005],belong[100005];

struct datae[100005];int head[100005];

struct segt[400005];

void ins(int u,int v,int w)

void insert(int u,int v,int w)

void dfs1(int x,int f)

}void dfs2(int x,int chain)

int lca(int x,int y)

void build(int k,int l,int r)

int mid=(l+r)>>1;

build(k<<1,l,mid);build(k<<1|1,mid+1,r);

}void pushdown(int k)

void update(int k,int x,int y,int v)

int mid=(l+r)>>1;

if(y<=mid)update(k<<1,x,y,v);

else if(x>mid)update(k<<1|1,x,y,v);

else

}int ask(int k,int x)

void solveupdate(int x,int f,int v)

if(x!=f)update(1,pl[f]+1,pl[x],v);

}void solve()

{ build(1,1,n);

for(int i=1;i小結:考慮乙個最值問題我們通常考慮乙個式子可以更新什麼樣的情況下什麼樣的值,或者什麼樣的值可以被什麼樣情況的狀態更新。比如說我們在進行倍增floyd時,我們是想到了每一條對於每一條最短路來講,它的最後一條邊可以從那些點來更新,從而想到矩陣來一遍一遍乘。而這個操作可以用矩乘優化。這道題也是同理,我們想到每乙個點可以從哪種路徑來進行更新,我們想到了如上述的方法,又因為給出的是最短路樹,所以根節點到乙個點的最短路一定是最短路樹上的。更加說明了我們演算法的正確性。

bzoj3694 最短路 樹鏈剖分

給出乙個n個點m條邊的無向圖,n個點的編號從1 n,定義源點為1。定義最短路樹如下 從源點1經過邊集t到任意一點i有且僅有一條路徑,且這條路徑是整個圖1到i的最短路徑,邊集t構成最短路樹。給出最短路樹,求對於除了源點1外的每個點i,求最短路,要求不經過給出的最短路樹上的1到i的路徑的最後一條邊。第一...

Bzoj 3694 最短路 樹鏈剖分

time limit 5 sec memory limit 256 mb submit 67 solved 34 submit status discuss 給出乙個n個點m條邊的無向圖,n個點的編號從1 n,定義源點為1。定義最短路樹如下 從源點1經過邊集t到任意一點i有且僅有一條路徑,且這條路徑...

BZOJ 3694 最短路 樹鏈剖分 倍增

下個月就是noip10連測試,還有什麼大學先修課考試,這段時間一直很忙但是還是抽出時間來複習一下版子,前段時間一直在搞spfa的各種建模,這段時間就來複習一下資料結構吧。首先就來不太好打的樹鏈剖分。嗯,開心,就每天寫一點點居然叫了兩遍就ac了,剛準備自己出資料還沒出,就抱著嘗試的想法提交了,居然ac...