PAT 1003 Emergency题解及buglist

    技术2022-07-11  94

    文章目录

    题目概述解法最短路径条数求取所有最短路径中,点权和的最大值求取 核心代码buglist

    题目概述

    给出一张图,每个节点有权值,每条边也有边权(正)。 求:

    最短路的条数所有最短路径中,点权和的最大值

    解法

    题为单源最短路问题,本文使用了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

    此题图为无向图,最开始建图的时候忘记添加双向边的代码,wa的莫名其妙
    Processed: 0.011, SQL: 9