|
| 1 | +# [1595. Minimum Cost to Connect Two Groups of Points (Hard)](https://leetcode.com/problems/minimum-cost-to-connect-two-groups-of-points/) |
| 2 | + |
| 3 | +<p>You are given two groups of points where the first group has <code><font face="monospace">size<sub>1</sub></font></code> points, the second group has <code><font face="monospace">size<sub>2</sub></font></code> points, and <code><font face="monospace">size<sub>1</sub></font> >= <font face="monospace">size<sub>2</sub></font></code>.</p> |
| 4 | + |
| 5 | +<p>The <code>cost</code> of the connection between any two points are given in an <code><font face="monospace">size<sub>1</sub></font> x <font face="monospace">size<sub>2</sub></font></code> matrix where <code>cost[i][j]</code> is the cost of connecting point <code>i</code> of the first group and point <code>j</code> of the second group. The groups are connected if <strong>each point in both groups is connected to one or more points in the opposite group</strong>. In other words, each point in the first group must be connected to at least one point in the second group, and each point in the second group must be connected to at least one point in the first group.</p> |
| 6 | + |
| 7 | +<p>Return <em>the minimum cost it takes to connect the two groups</em>.</p> |
| 8 | + |
| 9 | +<p> </p> |
| 10 | +<p><strong>Example 1:</strong></p> |
| 11 | +<img alt="" src="https://assets.leetcode.com/uploads/2020/09/03/ex1.jpg" style="width: 322px; height: 243px;"> |
| 12 | +<pre><strong>Input:</strong> cost = [[15, 96], [36, 2]] |
| 13 | +<strong>Output:</strong> 17 |
| 14 | +<strong>Explanation</strong>: The optimal way of connecting the groups is: |
| 15 | +1--A |
| 16 | +2--B |
| 17 | +This results in a total cost of 17. |
| 18 | +</pre> |
| 19 | + |
| 20 | +<p><strong>Example 2:</strong></p> |
| 21 | +<img alt="" src="https://assets.leetcode.com/uploads/2020/09/03/ex2.jpg" style="width: 322px; height: 403px;"> |
| 22 | +<pre><strong>Input:</strong> cost = [[1, 3, 5], [4, 1, 1], [1, 5, 3]] |
| 23 | +<strong>Output:</strong> 4 |
| 24 | +<strong>Explanation</strong>: The optimal way of connecting the groups is: |
| 25 | +1--A |
| 26 | +2--B |
| 27 | +2--C |
| 28 | +3--A |
| 29 | +This results in a total cost of 4. |
| 30 | +Note that there are multiple points connected to point 2 in the first group and point A in the second group. This does not matter as there is no limit to the number of points that can be connected. We only care about the minimum total cost. |
| 31 | +</pre> |
| 32 | + |
| 33 | +<p><strong>Example 3:</strong></p> |
| 34 | + |
| 35 | +<pre><strong>Input:</strong> cost = [[2, 5, 1], [3, 4, 7], [8, 1, 2], [6, 2, 4], [3, 8, 8]] |
| 36 | +<strong>Output:</strong> 10 |
| 37 | +</pre> |
| 38 | + |
| 39 | +<p> </p> |
| 40 | +<p><strong>Constraints:</strong></p> |
| 41 | + |
| 42 | +<ul> |
| 43 | + <li><code><font face="monospace">size<sub>1</sub></font> == cost.length</code></li> |
| 44 | + <li><code><font face="monospace">size<sub>2</sub></font> == cost[i].length</code></li> |
| 45 | + <li><code>1 <= <font face="monospace">size<sub>1</sub></font>, <font face="monospace">size<sub>2</sub></font> <= 12</code></li> |
| 46 | + <li><code><font face="monospace">size<sub>1</sub></font> >= <font face="monospace">size<sub>2</sub></font></code></li> |
| 47 | + <li><code>0 <= cost[i][j] <= 100</code></li> |
| 48 | +</ul> |
| 49 | + |
| 50 | + |
| 51 | +**Related Topics**: |
| 52 | +[Dynamic Programming](https://leetcode.com/tag/dynamic-programming/), [Graph](https://leetcode.com/tag/graph/) |
| 53 | + |
| 54 | +## Solution 1. DP |
| 55 | + |
| 56 | +`dp[i][mask]` is the state of the first `i` node in the 1st group being connected, with mask representing which nodes of the 2nd group have been covered already by previous steps in the DFS. (`mask[k] = 1` if node `k` in the 2nd group is already connected). |
| 57 | + |
| 58 | +```cpp |
| 59 | +// OJ: https://leetcode.com/problems/minimum-cost-to-connect-two-groups-of-points/ |
| 60 | +// Author: github.com/lzl124631x |
| 61 | +// Time: O((M * 2^N) * N) |
| 62 | +// Space: O(M * 2^N) |
| 63 | +// Ref: https://leetcode.com/problems/minimum-cost-to-connect-two-groups-of-points/discuss/855041/C%2B%2BPython-DP-using-mask |
| 64 | +class Solution { |
| 65 | + int dp[13][4096] = {}; |
| 66 | + int dfs(vector<vector<int>> &cost, vector<int> &mn, int i, int mask) { |
| 67 | + if (dp[i][mask] != -1) return dp[i][mask]; |
| 68 | + int ans = i < cost.size() ? INT_MAX : 0; |
| 69 | + if (i < cost.size()) { |
| 70 | + for (int j = 0; j < cost[0].size(); ++j) { |
| 71 | + ans = min(ans, cost[i][j] + dfs(cost, mn, i + 1, mask | (1 << j))); // for nodes in the 1st group, use DP to get the min cost. |
| 72 | + } |
| 73 | + } else { |
| 74 | + for (int j = 0; j < cost[0].size(); ++j) { |
| 75 | + if ((mask & (1 << j)) == 0) ans += mn[j]; // for those unconnected nodes in the 2nd group, pick the min cost to connect to the 1st group |
| 76 | + } |
| 77 | + } |
| 78 | + return dp[i][mask] = ans; |
| 79 | + } |
| 80 | +public: |
| 81 | + int connectTwoGroups(vector<vector<int>>& cost) { |
| 82 | + memset(dp, -1, sizeof(dp)); |
| 83 | + vector<int> mn(cost[0].size(), INT_MAX); // mn[j] is the minimal cost to connect jth node in the 2nd group to a node in the 1st group |
| 84 | + for (int j = 0; j < mn.size(); ++j) { |
| 85 | + for (int i = 0; i < cost.size(); ++i) mn[j] = min(mn[j], cost[i][j]); |
| 86 | + } |
| 87 | + return dfs(cost, mn, 0, 0); |
| 88 | + } |
| 89 | +}; |
| 90 | +``` |
0 commit comments