-
Notifications
You must be signed in to change notification settings - Fork 22
/
Copy path3672.connecting-cities-with-minimum-cost.cpp
157 lines (142 loc) · 3.55 KB
/
3672.connecting-cities-with-minimum-cost.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
// Tag: Graph, Greedy, Union Find
// Time: O(ElogE)
// Space: O(E+V)
// Ref: Leetcode-1135
// Note: -
// There are `n` cities in this question, and their numbers range from 1 to n.
//
// At the same time, there is a `connections` array and $connections[i] = [a_i, b_i, c_i]$, which means that the cost of connecting cities $a_i$ and $b_i$ is $c_i$.
//
// Please return the minimum cost required to connect all cities.
// If all cities cannot be connected, return **-1**.
//
// **Example 1**
//
// Input:
//
// ```plaintext
// 3
// [[1,2,1], [2,3,2], [1,3,3]]
// ```
//
// Ouput:
//
// ```plaintext
// 3
// ```
//
// Explanation:
//
// Choose `[1,2,1]` and `[2,3,2]` to connect all n cities. At this time, the cost is the least, which is 3.
//
// **Example 2**
//
// Input:
//
// ```plaintext
// 3
// [[1,2,1]]
// ```
//
// Output:
//
// ```plaintext
// -1
// ```
//
// Explanation:
//
// Unable to connect all cities according to `connections`.
//
//
class Solution {
public:
/**
* @param n: the number of cities
* @param connections: the connection info between cities
* @return: nothing
*/
int minimumCost(int n, vector<vector<int>> &connections) {
// write your code here
unordered_map<int, vector<pair<int, int>>> graph;
for (auto x: connections) {
graph[x[0]].push_back(make_pair(x[1], x[2]));
graph[x[1]].push_back(make_pair(x[0], x[2]));
}
unordered_set<int> visited;
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> q;
q.push(make_pair(0, connections[0][0]));
int res = 0;
while (!q.empty()) {
pair<int, int> top = q.top();
q.pop();
int city = top.second;
int cost = top.first;
if (visited.count(city) > 0) {
continue;
}
visited.insert(city);
res += cost;
for (auto x: graph[city]) {
if (visited.count(x.first) == 0) {
q.push(make_pair(x.second, x.first));
}
}
}
return visited.size() == n ? res : -1;
}
};
class UnionFind {
public:
vector<int> nodes;
vector<int> sizes;
UnionFind(int n): nodes(n + 1), sizes(n + 1 , 1) {
for (int i = 0; i <= n; i++) {
nodes[i] = i;
}
}
int find(int a) {
if (a == nodes[a]) {
return a;
}
nodes[a] = find(nodes[a]);
return nodes[a];
}
bool connect(int a, int b) {
int root_a = find(a);
int root_b = find(b);
if (root_a == root_b) {
return false;
} else {
nodes[root_a] = root_b;
sizes[root_b] += sizes[root_a];
return true;
}
}
int sizeOf(int a) {
int root_a = find(a);
return sizes[root_a];
}
};
class Solution {
public:
/**
* @param n: the number of cities
* @param connections: the connection info between cities
* @return: nothing
*/
int minimumCost(int n, vector<vector<int>> &connections) {
// write your code here
sort(connections.begin(), connections.end(), [](vector<int> &a, vector<int> &b) {
return a[2] < b[2];
});
UnionFind uf(n);
int res = 0;
for (auto &x: connections) {
if (uf.connect(x[0], x[1])) {
res += x[2];
}
}
return uf.sizeOf(1) == n ? res: -1;
}
};