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;}