u110 災後重建

2022-05-22 05:18:09 字數 2695 閱讀 9475

time limit: 1 second

memory limit: 128 mb

b地區在**過後,所有村莊都造成了一定的損毀,而這場**卻沒對公路造成什麼影響。但是在村莊重建好之前,所有與未重建完成的村

莊的公路均無法通車。換句話說,只有連線著兩個重建完成的村莊的公路才能通車,只能到達重建完成的村莊。

給出b地區的村莊數n,村莊編號從0到n-1,和所有m條公路的長度,公路是雙向的。並給出第i個村莊重建完成的時間t[i],你可以認為是同

時開始重建並在第t[i]天重建完成,並且在當天即可通車。若t[i]為0則說明**未對此地區造成損壞,一開始就可以通車。之後有q個

詢問(x, y, t),對於每個詢問你要回答在第t天,從村莊x到村莊y的最短路徑長度為多少。如果無法找到從x村莊到y村莊的路徑,經過

若干個已重建完成的村莊,或者村莊x或村莊y在第t天仍未重建完成 ,則需要返回-1。

輸入檔案rebuild.in的第一行包含兩個正整數n,m,表示了村莊的數目與公路的長度。

第二行包含n個非負整數t[0], t[1], …, t[n – 1],表示了每個村莊重建完成的時間,資料保證了t[0] ≤ t[1] ≤ … ≤ t[n – 1]。

接下來m行,每行3個非負整數i, j, w,w為不超過10000的正整數,表示了有一條連線村莊i與村莊j的道路,長度為w,保證i≠j,且對於任

意一對村莊只會存在一條道路。

接下來一行也就是m+3行包含乙個正整數q,表示q個詢問。

接下來q行,每行3個非負整數x, y, t,詢問在第t天,從村莊x到村莊y的最短路徑長度為多少,資料保證了t是不下降的。

輸出檔案rebuild.out包含q行,對每乙個詢問(x, y, t)輸出對應的答案,即在第t天,從村莊x到村莊y的最短路徑長度為多少。如果在第t

天無法找到從x村莊到y村莊的路徑,經過若干個已重建完成的村莊,或者村莊x或村莊y在第t天仍未修復完成,則輸出-1。

對於30%的資料,有n≤50; 對於30%的資料,有t[i] = 0,其中有20%的資料有t[i] = 0且n>50; 對於50%的資料,有q≤100; 對於100%的資料,有n≤200,m≤n*(n-1)/2,q≤50000,所有輸入資料涉及整數均不超過100000。

4 5

1 2 3 4

0 2 1

2 3 1

3 1 2

2 1 4

0 3 5

42 0 2

0 1 2

0 1 3

0 1 4

-1-15

4

【題解】

這道題要利用floyd的原理來做。

我們floyd的3層迴圈如下。

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

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

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

if (w[i][j] > w[i][k]+w[k][j])

f[i][j] = w[i][k]+w[k][j];

這裡的k層迴圈(第一層)列舉的是經過哪一些點作為中間點來縮短i->j的距離。

可以理解為用了前k個點作為中間點來嘗試更新任意兩點之間的距離。

這點可以為我們所利用。

看一下我們的詢問。

x,y,time

如果t[x] 或者t[y]>time則肯定是輸出-1的。

對於其他的

我們可以在k層迴圈中的i,j迴圈完畢之後加上下面這些東西。

即for (k=1->n)

k層迴圈仍是列舉n個點。

如果t[k]<=a[now].time且t[k+1] <=a[now].time

則k可以繼續列舉。表示我們可以利用k和k+1來作為中間點更新任意兩點之間的距離。

如果遇到t[k]<=a[now].time且t[k+1]>a[now].time。

則表示我們最多只能用k來作為中間點更新任意兩點之間的距離了。

這時我們只能嘗試在利用前k個點之後輸出w[x][y]了。

不能再用k+1這個點了。因為k+1這個點在a[now].time時還沒有修建好。

遇到這樣的k之後。now++.(a[now].time是隨著now的增加遞增的)。

如果now遞增後t[k+1]<=a[now].time了。則可以繼續利用k+1來作為中間點更新任意兩點之間的距離。

怎麼樣?理解了吧。

然後我們把k層迴圈的下界改為0.

因為可能有在0時刻的詢問。

這個問題在腦子裡想的時候有點煩。但是寫下來其實還好。

然後要先將詢問存下來。

村莊從0--n-1有點麻煩。直接改成1--n,即輸入的時候x,y都遞增1。

【**】

#include #include struct question //用結構體把詢問存下來。

;int n, m, t[201] = , w[201][201], q; //t陣列是各個節點修建好的時間。

question a[50001] = ;

void input_data()

scanf("%d", &q);

for (int i = 1; i <= q; i++) //輸入q個詢問。 }

void get_ans()

now++; //看一下下乙個詢問是否符合要求。

} if (now > q) //如果詢問都輸出了則結束。

break; }}

int main()

災後重建 floyd演算法)

題目背景 b地區在 過後,所有村莊都造成了一定的損毀,而這場 卻沒對公路造成什麼影響。但是在村莊重建好之前,所有與未重建完成的村莊的公路均無法通車。換句話說,只有連線著兩個重建完成的村莊的公路才能通車,只能到達重建完成的村莊。題目描述 給出b地區的村莊數n,村莊編號從0到n 1,和所有m條公路的長度...

P1119 災後重建

原題鏈結 一開始直接想跑最短路 看了看詢問次數 放棄了 然後果斷看了題解 floyd 用啥都不會用它的好嗎 平常的最劣選擇 但是 它就是正解 floyd的原理 就是列舉中點 這裡 因為出題人 已經把詢問排好了序 只需要判斷中點 有沒有重建完成 把它加入圖中 include include inclu...

洛古1119 災後重建

題目背景 b地區在 過後,所有村莊都造成了一定的損毀,而這場 卻沒對公路造成什麼影響。但是在村莊重建好之前,所有與未重建完成的村莊的公路均無法通車。換句話說,只有連線著兩個重建完成的村莊的公路才能通車,只能到達重建完成的村莊。題目描述 給出b地區的村莊數n,村莊編號從0到n 1,和所有m條公路的長度...