u251 心靈的撫慰

2021-09-28 09:58:57 字數 1596 閱讀 4796

time limit: 1 second

memory limit: 128 mb

【問題描述】

【輸入格式】

第一行有兩個正整數n,m,分別表示程式個數和有多少對程式可以被神牛直接互相聯想。 以下m行,每行三個正整數,分別表示一種聯想的兩端的程式的編號(從1開始),以及進行這種聯想所需要的最短時間(≤3500)。

【輸出格式】

如果神牛無論如何都再也亂不回來了,輸出「he will never come back.」。 如果神牛能夠亂回來,請輸出神牛會亂多長時間。

【資料規模】

對於100% 的資料,n≤250。

sample input1

4 3

1 2 10

1 3 20

1 4 30

sample output1

he will never come back.

【題目鏈結】:

【題解】

for (int k = 1;k <= n;k++)

mi即為最小環

最小環是基於floyd演算法實現的;

因為當k層迴圈進行到第k層時,任意兩點之間通過中間節點1..k-1得到的最短路已經求出來了;

則我們列舉包含節點k的最小環(且除了k號節點外這個環裡的其他節點編號都小於k),即dis[i][j(i到j的最短路,注意i到j的最短路不會包括k),然後加上w[j][k]+w[k][i];這樣就是乙個環形了;然後取最小值,那麼就能搞出最小環了;

這裡的w陣列之所以要另用乙個陣列是因為如果直接寫dis[j][k]+dis[k][i];那麼你不能**j到k的路徑或k到i的路徑裡面會不會包含dis[i][j]中經過的點;如果有這種情況那麼就不能稱之為環了;

還有就是

for (int i = 1;i <= k-1;i++)

for (int j = i+1;j <= k-1;j++)

mi = min(mi,dis[i][j]+w[j][k]+w[k][i]);

這裡的j層迴圈必須從i+1開始,不然會出現兩個節點直接走過去然後又直接走回來的情況(而題目不允許這樣);(題目所給的邊是無向邊);

【完整**】

#include 

#include

#include

#include

#define ll long long

using

namespace

std;

const ll inf = 1e15;

const

int maxn = 300;

int n,m;

ll w[maxn][maxn],dis[maxn][maxn];

int main()

ll ans = inf;

for (int k = 1;k <= n;k++)

if (ans >= inf)

puts("he will never come back.");

else

cout

<< ans 0;}