PAT 1003 Emergency題解及buglist

題目概述

給出一張圖,每個節點有權值,每條邊也有邊權(正)。
求:

  1. 最短路的條數
  2. 所有最短路徑中,點權和的最大值

解法

題爲單源最短路問題,本文使用了Dijkstra算法(纔不是因爲第一天做PAT,只找到之前NOIP的Dijkstra板子,複製了一下就用了)

最短路徑條數求取

Dijkstra算法的核心在於鬆弛操作。如果要對最短路條數進行計數,只需要在鬆弛操作時加上技術操作即可。
設問題中起點爲s;當前選中邊起點爲u,終點爲v,權值爲val;s點到i點的當前最短路徑長爲dist[i],s點到i點的當前最短路徑有path_cnt[i]條。有如下兩種更新操作:

  • 如果當前的dist[u]+val < dist[v]
    即“之前到v的路徑不是最短路”。則更新dist[v]爲dist[u]+val,同時更新path_cnt[v]爲path_cnt[u]。“要去v當前只知道從u走過去這一條最短路,所以如果走到u共有path_cnt[u]條路的話,走到v的最短路條數也只有path_cnt[u]條路啦。
  • 如果當前的dist[u]+val == dist[v]
    即“找到了和之前最短路徑長度一條最短路”。則更新操作爲給新找到的最短路計數。走到u共有path_cnt[u]條路的話,新增的走到v的最短路條數就有path_cnt[u]條路啦。

所有最短路徑中,點權和的最大值求取

此問題和上一個問題思路一致:在找到“更短的路徑”時,更新team_cnt[e.v] = team_cnt[e.u] + a[e.v],在找到“同樣短的路徑”時,判斷這條路徑是否有更大的點權和,如果是,則更新team_cnt[e.v] = team_cnt[e.u] + a[e.v]

核心代碼

dist[s] = 0; 
path_cnt[s] = 1;
team_cnt[s] = a[s];

q.push(HeapNode(s, 0));
while (!q.empty()) {
    HeapNode x = q.top(); q.pop();
    int u = x.u;
    if (done[u]) continue;
    done[u] = true;
    for (int i = 0; i < g[u].size(); i++)
    {
        Edge& e = edges[g[u][i]];
        if (dist[e.v] == dist[e.u] + e.val)
        {
            path_cnt[e.v] += path_cnt[e.u];
            if (team_cnt[e.u] + a[e.v] > team_cnt[e.v])
            {
                team_cnt[e.v] = team_cnt[e.u] + a[e.v];
            }
        }
        if (dist[e.v] > dist[e.u] + e.val) 
        {
            dist[e.v] = dist[e.u] + e.val;
            q.push(HeapNode(e.v, dist[e.v]));
            path_cnt[e.v] = path_cnt[e.u];
            team_cnt[e.v] = team_cnt[e.u] + a[e.v];
        }
    }
}

buglist

  1. 此題圖爲無向圖,最開始建圖的時候忘記添加雙向邊的代碼,wa的莫名其妙
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章