TJOI2012 橋(最短路徑樹)

2021-09-27 08:22:34 字數 2696 閱讀 2618

一張有向圖,求去掉任意一條邊後使得最短路最長。求最長的最短路長度以及刪邊的方案數。

題解都說是最短路徑樹,但是實際上這棵樹不用建出來,所以也就是乙個思路而已。

首先找到一條最短路,可以知道能刪的邊肯定在這條路徑上。可以想象一下,就算有多條最短路也不用管,只要找出一條就好了。

然後試著刪掉一條邊,刪邊之後的最短路必然要經過至少一條不在這條路徑上的邊。我們列舉新最短路上的一條新邊,構造出這條最短路徑,那麼在原最短路徑上而不在新最短路徑上的某條邊刪掉時,就有可能會走這條新最短路。

那麼考慮構造這條新最短路。假設列舉到的邊是u->v,那麼新最短路就是s->u->v->ts->uv->t都是最短路樹上的路徑。

然後考慮如何貢獻答案。我們記f[i]表示原最短路上第i條邊刪掉之後能得到的最短路長度。那麼只要s->u->v->t不經過i,就可以貢獻給i。我們可以記ner[u][0/1]表示在正/反最短路樹上,離u最近的最短路徑上的點,即終點與u的lca。知道了這個,u->v貢獻給ner[u][0]->ner[v][1]這段路徑上的邊就可以了。

因為是線性的,所以線段樹,或者簡單一點,搞個並查集從小到大覆蓋就行。

注意不要用spfa。

圖論好題。

#include

#define pii pair

#define fi first

#define se second

#define mp make_pair

using

namespace std;

const

int n =

2e5+10;

const

int m =

4e5+10;

struct g

void

add_dir

(int _u,

int _v,

int _w)

void

add_undir

(int _u,

int _v,

int _w)

}g;int n, m, dis[2]

[n], pre[n][2

], ner[2]

[n], trs[n]

, pn;

bool inp[n]

, inp1[m]

;struct datadat[m]

;int dn, fa[n]

, fg[n]

, ans1, ans2;

queue<

int> que;

bool inq[n]

;priority_queue que1;

void

dij(

int s,

int d[n])}

for(

int i = g.h[u]

; i; i = g.nxt[i])}

}while

(!que1.

empty()

) que1.

pop();

}void

bfs(

int s,

int d[n]

,int ner[n])}

}}void

get_path()

inp[1]

=1; trs[1]

= pn+1;

bfs(

1, dis[0]

, ner[0]

);bfs(n, dis[1]

, ner[1]

);}bool

cmp(data x, data y)

intfind

(int x)

void

solve()

;}sort

(dat +

1, dat + dn +

1, cmp)

;for

(int i =

1; i <= pn +1;

++ i)

fa[i]

= i;

for(

int i =

1; i <= dn;

++ i)

for(

int j =

find

(dat[i]

.x); j <= dat[i]

.y; j =

find

(j))

ans1 =

0; ans2 =0;

for(

int i =

1; i <= pn;

++ i)

}int

main()

get_path()

;solve()

;if(ans1 == dis[0]

[n])

printf

("%d %d\n"

, ans1, m)

;else

printf

("%d %d\n"

, ans1, ans2)

;return0;

}

最短路徑樹

問題描述 所謂最短路徑樹,就是從s出發,沿著樹上的邊走到任意點i,那麼經過的這些邊的權值和就是s到i的最短路徑。dijkstra演算法或spfa演算法不僅可計算從起點s到各點的最短路徑長度,同時也可得到以s為根的最短路徑樹。方法是在進行鬆弛操作時,如果d i c d j 時,除了更新d j 之外,還...

最短路徑,最短路徑樹和最小生成樹

首先介紹這三個概念,很多人都聽過最短路徑了,但是最短路徑樹卻很少聽過,關於最短路徑樹的介紹也不太多。而最短路徑樹和最小生成樹更是完全不同的兩個概念。最短路徑就是從乙個指定的頂點出發,計算從該頂點出發到其他所有頂點的最短路徑。通常用dijkstra演算法,floyd演算法求解。最短路徑樹spt sho...

SPF(最短路徑樹)演算法

構造一棵樹 a 使n個節點之間的總長最小 樹是乙個在每兩個節點之間僅有一條路徑的圖 在我們給出構造過程中,分支被分成3個集合 被明確分配給構造中的樹的分支 他們將在子樹中 這個分支的隔壁分枝被新增到集合1 剩餘的分支 拋棄或不考慮 節點被分成兩個集合 a 被集合1中的分支連線的節點 b 剩餘的節點 ...