【[USACO09DEC]牛收費路徑Cow Toll Paths】
阿新 • • 發佈:2019-01-02
很妙的一道題,我之前一直是用一個非常暴力的做法
就是列舉點權跑堆優化dijkstra
但是詢問次數太多了
於是一直只有50分
今天終於抄做了這道題,不貼程式碼了,只說一下對這道題的理解
首先點權和邊權不能混在一起,這是公認的,畢竟這個樣子完全沒有辦法處理
那我們為什麼要排序呢,發現其餘幾篇題解好像也沒講清楚
說得好像我能講清楚一樣
我們對於所有點按點權進行了一個排序,這一點很令人玩味,這是為什麼呢
首先我們的floyd的列舉是長這個樣子的
for(re int k=1;k<=n;k++) for(re int i=1;i<=n;i++) for(re int j=1;j<=n;j++)
最外層列舉的\(k\)是列舉的什麼
中轉點啊
那我們排序完了之後說明什麼
說明我們中轉點加入的順序是從小到大的
於是我們在找\(i\),\(j\)之間的最短路的時候,我們的中轉點如果只是列舉到了\(k1\)
那麼這又說明了什麼
這說明了我們當前的\(i\),\(j\)之間的最短路中並沒有點權超過\(k1\)的點
於是當前這條最短路上除去起點和終點點權最大的也就是\(k1\)了
那麼我們就可以這樣更新了
dist[i][j]=min(dist[i][j],d[i][j]+max(nm[k].d,max(nm[i].d,nm[j].d)))
這是從樓下的那位大佬程式碼裡抄來的
怎麼說呢
我們當前的k越大,說明我們的最短路中可能的中轉點越多,最短路也就越短(儘管可能隨著\(k\)增大最短路並不會變短,而是不變),但是同時我們加入的中轉點的點權也越來越大
也就是說我們每次新加入一箇中轉點,可能最短路是變短了,但是我們的點權最大值也增加了,這個時候就要與前面的dist值取一個最小了
於是程式碼就不貼了