[ 第 79 场力扣双周赛 III ] 6085. 道路的最大总重要性

208 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第1天,点击查看活动详情

每日刷题 2022.05.29

题目

  • 给你一个整数n ,表示一个国家里的城市数目。城市编号为 0 到 n - 1
  • 给你一个二维整数数组 roads ,其中 roads[i] = [ai, bi] 表示城市 ai 和 bi 之间有一条 双向 道路。
  • 你需要给每个城市安排一个从 1 到 n 之间的整数值,且每个值只能被使用 一次 。道路的 重要性 定义为这条道路连接的两座城市数值之和。
  • 请你返回在最优安排下,所有道路重要性之和最大为多少。

示例

  • 示例1 image.png
输入:n = 5, roads = [[0,1],[1,2],[2,3],[0,2],[1,3],[2,4]]
输出:43
解释:上图展示了国家图和每个城市被安排的值 [2,4,5,3,1] 。
- 道路 (0,1) 重要性为 2 + 4 = 6 。
- 道路 (1,2) 重要性为 4 + 5 = 9 。
- 道路 (2,3) 重要性为 5 + 3 = 8 。
- 道路 (0,2) 重要性为 2 + 5 = 7 。
- 道路 (1,3) 重要性为 4 + 3 = 7 。
- 道路 (2,4) 重要性为 5 + 1 = 6 。
所有道路重要性之和为 6 + 9 + 8 + 7 + 7 + 6 = 43 。
可以证明,重要性之和不可能超过 43
  • 示例2 image.png
输入:n = 5, roads = [[0,3],[2,4],[1,3]]
输出:20
解释:上图展示了国家图和每个城市被安排的值 [4,3,2,5,1] 。
- 道路 (0,3) 重要性为 4 + 5 = 9 。
- 道路 (2,4) 重要性为 2 + 1 = 3 。
- 道路 (1,3) 重要性为 3 + 5 = 8 。
所有道路重要性之和为 9 + 3 + 8 = 20 。
可以证明,重要性之和不可能超过 20

提示

  • 2 <= n <= 5 * 10^4
  • 1 <= roads.length <= 5 * 10^4
  • roads[i].length == 2
  • 0 <= ai, bi <= n - 1
  • ai != bi
  • 没有重复道路。

解题思路

  • 分析:roads[i] = [ai, bi] 表示城市 aibi 之间有一条 双向道路。也就是说是无向图,因此两个城市相连的一条道路,既是属于a城市的也是属于b城市的。
  • 需要给每个城市安排一个整数值1 ~ n,使得道路的重要性之和最大
  • 那么分析到这里,使用贪心的思维可以想到,当然是城市道路数最多的乘以n,依次往下递减这样得到的,道路重要性之和最大

具体实现

  • 统计每个城市拥有的总的道路数,记为ans数组
  • ans数组进行降序排序后,此时ans[0]就是最大的数,因此给ans[0] * n、ans[1] * n - 1 ..... ans[n - 1] * 1,最终将这些结果加和,就可以得到最终的结果
  • 分析:有人可能会考虑,排序的时候,不是将哪个城市对应的道路总数丢失了吗?是的,其实这里没有必要再记录是哪座城市对应的道路总数,因为最终的结果只取决于:道路数 * n ~ 1的值加和

AC代码

var maximumImportance = function(n, roads) {
  let r = roads, ans = new Array(n).fill(0), m = r.length;
  // 因为是 城市a和城市b之间有一条双向的通道,因此是无向图,统计每个城市出来的有几条道路
  for(let i = 0; i < m; i++) {
    let x = r[i][0], y = r[i][1];
    ans[x]++;
    ans[y]++;
  }
  // 将每个城市拥有的道路总数升序排序
  ans.sort((a, b) => {
    return b - a;
  });
  // 按照最大的城市道路总数 * n,这样依次往下
  let sum = 0, t = n;
  for(let i = 0; i < n; i++) {
    sum += ans[i] * t;
    t--;
  }
  return sum;
};

总结

  • 仔细分析题目,想好后再开始写代码,比如这道题,最终的结果和哪座城市是没有关系的。