洛谷 P2829 大逃離 題解

2021-10-05 07:10:37 字數 2679 閱讀 1821

題目鏈結

一道模板的次短路

設 d is

[x],

dist

[x

]dis[x],dist[x]

dis[x]

,dis

t[x]

分別為點 1

11 到 x

xx 的最短路和次短路長度

我們只需在跑最短路時,順帶更新一下次短路

由於每個點可以經過多次,我們只能使用 spfa

對於每條邊 [x,

y]

[x,y]

[x,y

],考慮 dis

t[y]

dist[y]

dist[y

] 的轉移:

最無腦的一種,dis

t[y]

=dis

t[x]

+w(x

,y

)dist[y]=dist[x]+w(x,y)

dist[y

]=di

st[x

]+w(

x,y)

,其中 w(x

,y

)w(x,y)

w(x,y)

為當前邊的長度

在最短路中,進行鬆弛操作後,滿足當前的 dis

[y

]dis[y]

dis[y]

小於鬆弛前的 dis

[y

]dis[y]

dis[y]

。那麼,我們就可以用鬆弛前的 dis

[y

]dis[y]

dis[y]

去更新 dis

t[y]

dist[y]

dist[y

]如果,dis

[y

]

s[x]

+w(x

,y

)dis[y]di

s[y]

s[x]

+w(x

,y),說明 dis

[x]+

w(x,

y)

dis[x]+w(x,y)

dis[x]

+w(x

,y) 是一條次短路,所以 dis

t[y]

=min

(dis

t[y]

,dis

[x]+

w(x,

y)

)dist[y]=min(dist[y],dis[x]+w(x,y))

dist[y

]=mi

n(di

st[y

],di

s[x]

+w(x

,y))

。注意:這裡更新的時間是在鬆弛操作之後

關鍵**

for

(int i=

0;i.size()

;++i)

else

if(dist[y]

>tmp && tmp!=dis[y]

)// 如果 dis[x]+e[x][i].len 是一條次短路

if(dist[y]

>dist[x]

+e[x]

[i].len)

}

這裡說一下,題目中提到的:乙個點所直接連線的地方數量

這裡的數量並不等於這個節點的度數(連邊數),因為兩個節點之間可能有多條邊。這才是正確的開啟方式:

for

(int x=

1;x<=n;

++x)

memset

(vis,0,

sizeof

(vis));

}

完整**

#include

#include

#include

#include

#include

#include

using

namespace std;

const

int maxn=

10010

,inf=

0x3f3f3f3f

;struct edge};

int dis[maxn]

,dist[maxn]

,d[maxn]

;bool vis[maxn]

;int n,m,k;

vector e[maxn]

;void

spfa()

else

if(dist[y]

>tmp && tmp!=dis[y])if

(dist[y]

>dist[x]

+e[x]

[i].len)}}

}int

main()

for(

int x=

1;x<=n;

++x)

memset

(vis,0,

sizeof

(vis));

}spfa()

;if(dist[n]

==inf)

puts

("-1");

else

printf

("%d\n"

,dist[n]);

return0;

}

洛谷P1373小a和uim大逃離題解

這個題好坑啊,首先是他會卡空間,然後我們就只能把一種比較好理解的狀態給捨棄,因為空間開不下,然而採用一種難理解的狀態就是 dp i j l 0 1 表示 i j 位置,兩者的差為 l 當前由誰來吸收的方案數。然後我們就可以推出狀態轉移方程,此狀態轉移方程很好寫,主要就是狀態非常難想,因此我們如果狀態...

洛谷 P1095 守望者的逃離題解

解題思路 首先dp的套路就是先找狀態,這題也找不出其他的狀態了,只有時間乙個,所以用f i 表示時刻i能走多遠。仔細一想實際上決策只有跑 閃現 停三種決策 然而閃現的耗藍要和跑步一同計算十分麻煩。於是把它們分開算 先算閃現的,有以下框架 for i in range 1,t 如果藍量夠 閃現,耗藍 ...

洛谷2758 編輯距離 題解

字串編輯距離板子題,留乙個底,方便日後。設a和b是兩個字串。我們要用最少的字元操作次數,將字串a轉換為字串b。這裡所說的字元操作共有三種 1 刪除乙個字元 2 插入乙個字元 3 將乙個字元改為另乙個字元 皆為小寫字母!題解網上搜一大堆 其實光看 也都能看懂這道題。include include in...