讓我們一起來%forever_shi神犇
題意:給你乙個n
nn個點m
mm條邊的有向帶權圖,設1
11號點到n
nn號點的最短路是dis
disdi
s,給你乙個k(k
<=50
)k(k<=50)
k(k<=5
0),求所有1
11到n
nn的路徑中長度不超過dis
+k
dis+k
dis+
k的數量。
題解:顯然我們要先處理出最短路,如果k=0
k=0k=
0,就是最短路計數了。要做計數,我們不難想到要在圖上dpdp
dp。我們發現只要有乙個邊權全部是0
00的環,那麼我們的滿足題意的路徑就會有無數條,因為可以在環裡轉任意多圈之後再出來。那麼我們要判斷是否有無窮多解就是去找有沒有全部是0
00的環。
我們可以先處理出乙個最短路圖,最短路圖的含義是由所有dis
[x]+
w[x]
[y]=
dis[
y]
dis[x]+w[x][y]=dis[y]
dis[x]
+w[x
][y]
=dis
[y]的邊連成的圖,最短路圖的乙個性質:如果邊權都是正數,那麼最短路圖是乙個dag。dag是可以拓撲排序的,如果最後每個點入度都是0
00,就不存在權值全是0
00的環,否則就是有權值全是0
00的環,因為權值是0
00的邊一定不會讓兩點之間的最短路變長,所以其就一定會在最短路圖上,而形成環的話是沒法有其中某乙個點的入度是0
00,因此判斷拓撲排序後的入度即可。
對圖拓撲排序後根據圖的拓撲序在dag上dpdp
dp也是乙個經典套路,這裡我們就會採用這個套路。我們設dp[
i][j
]dp[i][j]
dp[i][
j]表示對於點i
ii比dis
[i
]dis[i]
dis[i]
大j
jj的路徑數,那麼對於路徑x
−>
yx−>y
x−>
y,狀態轉移方程即為:dp[
y][j
+w(x
,y)−
(dis
[y]−
dis[
x])]
+=dp
[x][
j]
dp[y][j+w(x,y)−(dis[y]−dis[x])]+=dp[x][j]
dp[y][
j+w(
x,y)
−(di
s[y]
−dis
[x])
]+=d
p[x]
[j]。
那麼我們列舉j
jj,然後按照拓撲序列舉x
xx,再列舉從x
xx出發的所有邊,進行dpdp
dp。注意外層是列舉j
jj,因為在dpdp
dp的過程中如果外層列舉x
xx的話dag上是沒有環的,但是這裡的邊是列舉原圖的邊,所以可能之後會有環再回到x
xx,得到答案就是錯誤的了。還有就是這個dpdp
dp看似列舉的層數很多,但是其實複雜度並不高,因為所有邊都只會被列舉到一次,所有點都只會被列舉k+1
(0到k
)k+1(0到k)
k+1(0到
k)次,所以總的複雜度是o(n
∗k
)o(n∗k)
o(n∗k)
的。最後答案就是∑i=
0kdp
[n][
i]
了\sum^k_dp[n][i]了
∑i=0k
dp[n
][i]
了 (吸氧苟過去qaq)
#include
#define ll long long
#define rint register int
using
namespace std;
const
int maxn=
201000
;struct node
e[maxn]
,a[maxn]
;int head[maxn]
,head1[maxn]
,num,num1,i;
int dis[maxn]
,n,m,t,k,p,rd[maxn]
,numm[maxn]
;int que[maxn]
,ji,u,v,d;
ll dp[
200200][
55],ans;
bool book[maxn]
;priority_queueint,
int>
> q;
intread()
while
(c>=
'0'&&c<=
'9')
return x*y;
}void
add(
int from,
int to,
int dis)
void
add1
(int from,
int to,
int dis)
void
dij(
int s)}}
}void
topsort()
h++;}
}int
main()
dij(1)
;for
(rint i=
1;i<=num;
++i)
}topsort()
;for
(rint i=
1;i<=n;
++i)
if(rd[i])if
(flag)
dp[1]
[0]=
1;for(rint k=
0;k<=k;
++k)
for(rint i=
1;i<=n;
++i)
}for
(rint i=
0;i<=k;
++i)
ans=
(ans%p+dp[n]
[i]%p)
%p;printf
("%d\n"
,ans);}
return0;
}
離散化 拓撲排序 最短路堆優化
資料範圍太大,自身無法作為陣列的下標儲存對應的屬性,當資料至於他們之間的相對大小有關,而與具體值無關時,則可以進行離散化。做法 不改變資料相對大小的前提下,對資料進行縮小 struct node a 100001 從小到大排序 b 100001 for i 1 i n i b a i order i...
CSP模擬賽 益智遊戲(最短路 拓撲排序)
題目描述 小p和小r在玩一款益智遊戲。遊戲在乙個正權有向圖上進行。小p 控制的角色要從a 點走最短路到b 點,小r 控制的角色要從c 點走最短路到d 點。乙個玩家每回合可以有兩種選擇,移動到乙個相鄰節點或者休息一回合。假如在某一時刻,小p 和小r 在相同的節點上,那麼可以得到一次特殊獎勵,但是在每 ...
道路與航線(最短路 縮點 拓撲排序)
題目描述 農夫約翰正在乙個新的銷售區域對他的牛奶銷售方案進行調查。他想把牛奶送到t個城鎮,編號為1 t。這些城鎮之間通過r條道路 編號為1到r 和p條航線 編號為1到p 連線。每條道路 i 或者航線 i 連線城鎮ai到bi,花費為ci。對於道路,0 ci 10,000 然而航線的花費很神奇,花費ci...