bzoj3694 最短路 樹鏈剖分

2021-07-10 12:30:35 字數 1660 閱讀 3061

給出乙個n個點m條邊的無向圖,n個點的編號從1~n,定義源點為1。定義最短路樹如下:從源點1經過邊集t到任意一點i有且僅有一條路徑,且這條路徑是整個圖1到i的最短路徑,邊集t構成最短路樹。

給出最短路樹,求對於除了源點1外的每個點i,求最短路,要求不經過給出的最短路樹上的1到i的路徑的最後一條邊。

第一行包含兩個數n和m,表示圖中有n個點和m條邊。

接下來m行,每行有四個數ai,bi,li,ti,表示圖中第i條邊連線ai和bi權值為li,ti為1表示這條邊是最短路樹上的邊,ti為0表示不是最短路樹上的邊。

輸出n-1個數,第i個數表示從1到i+1的要求的最短路。無法到達輸出-1。

5 93 1 3 1

1 4 2 1

2 1 6 0

2 3 4 0

5 2 3 0

3 2 2 1

5 3 1 1

3 5 2 0

4 5 4 0

6 7 8 5

對於100%的資料,n≤4000,m≤100000,1≤li≤100000

題解:首先建出最短路徑樹。

對於一條不在最短路徑樹里的邊,

設該邊的兩端點為x,y.t為x和y的最近公共祖先,dis[i]表示1到i的最短距離.

那麼對於x和t之間的點u,一定存在1-t-y-x-u的路徑。路徑長度為d[y]+v(x,y)+d[x]-d[u].

我們需要最小化d[x]+d[y]+v(x,y).y和t之間的點同理。

所以我們列舉每一條不在最短路徑樹里的邊.更新兩端點和lca之間的點即可。

這些顯然可以用樹鏈剖分解決。

**:

#include#include#include#define n 100010

int pos[n],bl[n],point[n],next[n],t[n*4],p[n*4],size[n];

int f,cnt,num,sz,n,m,x,y,w,fa[n][20],dis[n],deep[n];

struct usee[n];

struct use2b[n];

using namespace std;

void add(int x,int y,int w)

void dfs(int x)

int lca(int x,int y)

void paint(int k,int v)

void pushdown(int k,int v)

void add(int k,int l,int r,int ll,int rr,int v)

if (ll<=mid) add(k<<1,l,mid,ll,rr,v);

if (rr>mid) add(k<<1|1,mid+1,r,ll,rr,v);

t[k]=min(t[k<<1],t[k<<1|1]);

}int ask(int k,int l,int r,int x)

void solveadd(int x,int y,int v)

if (x!=y) add(1,1,sz,pos[y]+1,pos[x],v);

}void solve()

for (int i=2;i<=n;i++)

}int main()

dfs(1),dfs2(1,1);solve();

}

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...

bzoj3694 最短路 樹鏈剖分 線段樹

最短路 bzoj 3694 題目大意 給你乙個n個點m條邊的無向圖,源點為1,並且以點1為根給出最短路樹。求對於2到n的每個點i,求最短路,要求不經過給出的最短路樹上的1到i的路徑上的最後一條邊。注釋 1 le n le 4000 1 le m le 10 5 想法 對於任意兩個點u和v,滿足u和v...