洛谷P3953 逛公園

2021-08-20 01:34:05 字數 2382 閱讀 5866

題目

#題解:

f[u][k] 表示 dis(u,n)<=mindis(u,n)+k的方案數,答案就是 f[1][k]

f[u][k]=∑f[v][k−mindis(v,n)+mindis(u,n)-w]

這樣怎麼判 0環呢?只要在搜尋的時候記錄個 instack 就 ok 了

如果當前的 v還在搜尋的棧中就可以直接返回 -1了

不過,有一種情況例外:0環所在的路徑不符合條件

比如這個圖:

1 2 1

2 5 1

1 3 1

3 4 0

4 3 0

4 5 100

但是我手造了一些資料都卡不掉這個程式,就姑且認為這程式是對的吧。

好像最正確的解法應該要加上拓撲排序

#include

using

namespace std;

const

int n=

100003

,m=200003

;struct nodee[m<<1]

;int h1[n]

,hn[n]

,dis[n]

,n,m,k,p,in[n][51

],f[n][51

],tot,t,u,v,w;

char ss[

1<<17]

,*a=ss,

*b=ss;

inline

chargc(

)template

<

class

t>

inline

void

read

(t&x)

namespace segment

void

clr(

)int

cmp(

int a,

int b)

void

mdy(

int x,

int w)

void

del(

int x)

}using

namespace segment;

void

add(

int u,

int v,

int w,

int*h)

; h[u]

=tot;

}void

mod(

int&x)

void

dij()}

intdfs

(int u,

int k)

in[u]

[k]=0;

return f[u]

[k];

}int

main()

dij();

printf

("%d\n"

,dfs(1

,k));}

}

如果zkw線段樹看不懂也沒關係,可以用spfa做,差不多快,但是理解起來方便多了

#include

using

namespace std;

const

int n=

100003

,m=200003

;struct nodee[m<<1]

;int h1[n]

,hn[n]

,dis[n]

,n,m,k,p,in[n][51

],f[n][51

],tot,t,u,v,w,q[m*10]

,vis[n]

;char ss[

1<<17]

,*a=ss,

*b=ss;

inline

chargc(

)template

<

class

t>

inline

void

read

(t&x)

void

add(

int u,

int v,

int w,

int*h)

; h[u]

=tot;

}void

mod(

int&x)

void

spfa()

}}}int

dfs(

int u,

int k)

in[u]

[k]=0;

return f[u]

[k];

}int

main()

spfa()

;printf

("%d\n"

,dfs(1

,k));}

}

洛谷P3953 逛公園

發現 k leq 50 猜想時間複雜度肯定與 k 有關。令 dis x 表示 1 到 x 的最短路。考慮 dp。先不考慮無限解得情況,設 f x i 表示到達點 x 走過的路程長度為 dis x i 的方案數。那麼 f x i 肯定由一條邊 y,x 轉移而來。設 y,x 的長度為 d 則這條路徑到 ...

題解 洛谷P3953 逛公園(最短路 動態規劃)

noip2017最難的題目。這裡給一種比較方便理解的做法。拿到這個題目,啥也不用想,首先得把最短路求出來。然而求最短路時我們要反著建圖,也就是求出n到其他所有點的最短路。為什麼這樣做呢?因為這樣可以避免正向某個點無法到達n點的情況。求出最短路後,我們可以利用動態規劃解決這個問題。首先考慮沒有0邊的情...

洛谷3953 逛公園(DP)

原題 這道題目看到k特別小,而且k n的空間不會gg,那麼我們考慮乙個dp對吧。設 dp i k 表示到了點i與最短路相差k值的方案數,然後直接記搜 不想用拓撲序列 就可以了。luogu judger enable o2 include include include include include...