題目
#題解:
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...