洛谷1685 遊覽 拓撲排序 DP

2022-05-31 09:24:15 字數 2518 閱讀 2853

順利通過了黃藥師的考驗,下面就可以盡情遊覽桃花島了!

你要從桃花島的西頭開始一直玩到東頭,然後在東頭的碼頭離開。可是當你遊玩了一次後,發現桃花島的景色實在是非常的美麗!!!於是你還想乘船從桃花島東頭的碼頭回到西頭,再玩一遍,但是桃花島有個規矩:你可以遊覽無數遍,但是每次遊玩的路線不能完全一樣。

我們把桃花島抽象成了乙個圖,共\(n\)個點代表路的相交處,\(m\)條邊表示路,邊是有向的(只能按照邊的方向行走),且可能有連線相同兩點的邊。輸入保證這個圖沒有環,而且從西頭到東頭至少存在一條路線。兩條路線被認為是不同的當且僅當它們所經過的路不完全相同。

你的任務是:把所有不同的路線遊覽完一共要花多少時間?

第\(1\)行為\(5\)個整數:\(n、m、s、t、t0\),分別表示點數,邊數,島西頭的編號,島東頭的編號(編號是從1到n)和你乘船從島東頭到西頭一次的時間。

以下\(m\)行,每行3個整數:\(x、y、t\),表示從點x到點y有一條行走耗時為t的路。

每一行的多個資料之間用乙個空格隔開,且:\(2<=n<=10000; 1<=m<=50000;t<=10000;t0<=10000\)

假設總耗時為\(total\),則輸出\(total\)

\(mod\)

\(10000\)的值(\(total\)對\(10000\)取餘)。

3 4 1 3 7

1 2 5

2 3 7

2 3 10

1 3 15

56
樣例解釋

共有\(3\)條路徑可以從點\(1\)到點\(3\),分別是\(1-2-3,1-2-3,1-3\)。

時間計算為:\((5+7)+7 +(5+10)+7 +(15)=56\)

我們定義

\(cnt[i]\)表示到點\(i\)的次數;

\(dis[i]\)表示到點\(i\)的總路徑長度。

所以\(ans=dis[t]+(cnt[t]-1)*t0\)

如何去轉移\(cnt\)和\(dis\)陣列呢

\(dfs\)一遍不就行了

考慮一條邊從\(u\)到\(v\),邊權為\(w\)

\(dis[v]=dis[v]+dis[u]+cnt[u]*w;\)

\(cnt[v]+=cnt[u];\)

初始化:\(cnt[s]=1\)

但是絕對不能直接\(dfs\)去遍歷,只能得\(20\)分。

我一開始就直\(dfs\),還是太菜了(20分)。

#include#include#include#include#include#define ll long long

#define r register

#define mod 10000

#define n 50005

using namespace std;

templateinline void read(t &a)

while(isdigit(c))

a=f*x;

}int n,m,s,t,ti,tot,h[n];

ll cnt[n],dis[n];

struct nodeedge[n<<1];

inline void add(r int u,r int v,r int w)

inline void dfs(r int x)

}int main()

cnt[s]=1;

dfs(s);

printf("%lld\n",(dis[t]+(cnt[t]-1)*ti)%mod);

return 0;

}

為什麼這樣不對??

因為有一些點的資訊我們還沒有收集全面就用它去更新其他點了。

如何解決(感謝\(wtx\)大佬指導),

拓撲排序呀,當乙個點入度為0時就說明已經沒有點可以去更新它了,說明它的資訊收集已經完全了。

正確的**:

#include#include#include#include#include#define ll long long

#define r register

#define mod 10000

#define n 50005

using namespace std;

templateinline void read(t &a)

while(isdigit(c))

a=f*x;

}int n,m,s,t,ti,tot,h[n],in[n];

ll cnt[n],dis[n];

struct nodeedge[n<<1];

inline void add(r int u,r int v,r int w)

inline void dfs(r int x)

}int main()

cnt[s]=1;

dfs(s);

printf("%lld\n",(dis[t]+(cnt[t]-1)*ti)%mod);

return 0;

}

洛谷 P1685 遊覽

手玩樣例,我們很快 從題目後的提示 找到了 1 3 1 3 1 3,1 2 31 2 3 1 2 3,1 2 31 2 3 1 2 3 兩者不同 一共三條路徑。求出其權值之和再加上乘船返回兩次所需的時間,和樣例恰好一致。於是我們便可以把這個問題分成兩個子問題逐個求解 選擇從起點開始dfs,我們需要考...

洛谷P1137 旅行計畫(拓撲排序 dp)

題目描述 小明要去乙個國家旅遊。這個國家有n個城市,編號為1 n,並且有m條道路連線著,小明準備從其中乙個城市出發,並只往東走到城市i停止。所以他就需要選擇最先到達的城市,並制定一條路線以城市i為終點,使得線路上除了第乙個城市,每個城市都在路線前乙個城市東面,並且滿足這個前提下還希望遊覽的城市盡量多...

洛谷 P1137 旅行計畫 (拓撲排序 dp)

在dag中,拓撲排序可以確定dp的順序 把圖的資訊轉化到乙個拓撲序上 注意轉移的時候要用邊轉移 這道題的dp是用刷表法 include define rep i,a,b for register int i a i b i define for i,a,b for register int i a ...