2285. Maximum Total Importance of Roads

Dare2Solve

Dare2Solve

2285. Maximum Total Importance of Roads
SAMSUNG 49-Inch Odyssey G9
SAMSUNG 49-Inch Odyssey G9
Because earth is not flat

Intuition

The problem involves assigning values to cities such that the total importance of all roads is maximized. The importance of a road is the sum of the values of the cities it connects. To maximize the total importance, we should assign the highest values to the cities that appear most frequently in the roads array. This is because the importance of each road increases with the values of the cities it connects.

Approach

  1. Calculate Frequencies:
    • Create a frequency array to count the number of roads connected to each city.
    • Traverse through the roads array and increment the counts for the connected cities.
  2. Sort Frequencies using Counting Sort:
    • Use counting sort to sort cities based on their frequencies. This is more efficient than a general-purpose sort when the range of frequency values is small compared to the number of cities.
  3. Assign Values Optimally:
    • Assign the highest available values to the cities with the highest frequencies.
    • Calculate the total importance by summing the importance of each road using the assigned values.

Complexity

Code Explanation

1. Initialize Arrays and Variables

var freq = new Uint32Array(n);
var cnt = new Uint32Array(n);
var res = 0;
var cur = 1;

2. Count the Frequency of Each City

roads.forEach(([a, b]) => { 
    ++freq[a], ++freq[b] 
});

3. Count the Number of Cities with Each Frequency

freq.forEach((x) => ++cnt[x]);

4. Assign Values to Cities Based on Their Frequencies

cnt.forEach((x, idx) => { 
    while (x--)
        res += idx * cur++ 
});

5. Return the Maximum Total Importance

return res;

Code

C++

class Solution {
public:
    long long maximumImportance(int n, vector<vector<int>>& roads) {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        cout.tie(nullptr);

        vector<int> freq(n, 0);
        vector<int> cnt(n, 0);
        long long res = 0;
        long long cur = 1;

        for (const auto& road : roads) {
            ++freq[road[0]];
            ++freq[road[1]];
        }

        for (const auto& x : freq) {
            ++cnt[x];
        }

        for (long long idx = 0; idx < cnt.size(); ++idx) {
            for (int i = cnt[idx]; i > 0; --i) {
                res += idx * cur++;
            }
        }

        return res;
    }
};

Python

class Solution:
    def maximumImportance(self, n: int, roads: List[List[int]]) -> int:
        freq = [0] * n
        cnt = [0] * n
        res = 0
        cur = 1

        for road in roads:
            freq[road[0]] += 1
            freq[road[1]] += 1

        for x in freq:
            cnt[x] += 1

        for idx in range(len(cnt)):
            for _ in range(cnt[idx], 0, -1):
                res += idx * cur
                cur += 1

        return res

Java

class Solution {
    public long maximumImportance(int n, int[][] roads) {
        int[] freq = new int[n];
        int[] cnt = new int[n];
        long res = 0;
        long cur = 1;

        for (int[] road : roads) {
            freq[road[0]]++;
            freq[road[1]]++;
        }

        for (int x : freq) {
            cnt[x]++;
        }

        for (int idx = 0; idx < cnt.length; ++idx) {
            for (int i = cnt[idx]; i > 0; --i) {
                res += idx * cur++;
            }
        }

        return res;
    }
}

JavaScript

/**
 * @param {number} n
 * @param {number[][]} roads
 * @return {number}
 */
var maximumImportance = function (n, roads) {
    var freq = new Uint32Array(n);
    var cnt = new Uint32Array(n);
    var res = 0;
    var cur = 1;

    roads.forEach(([a, b]) => { ++freq[a], ++freq[b] });
    freq.forEach((x) => ++cnt[x]);
    cnt.forEach((x, idx) => { while(x--) res += idx * cur++ });

    return res;
};