fork download
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. typedef long long ll;
  6. typedef pair<int, int> ii;
  7.  
  8. const int INF = 1e9;
  9. const ll LINF = 1e18;
  10.  
  11. const int N = 3e2 + 5;
  12.  
  13. struct Edge {
  14. int u, v, w;
  15. bool operator<(const Edge& other) const {
  16. return w < other.w;
  17. }
  18. };
  19.  
  20. int n;
  21. int w[N];
  22. vector<Edge> edges;
  23.  
  24. int p[N], sz[N];
  25.  
  26. void initSet() {
  27. for (int u = 0; u <= n; u++) {
  28. p[u] = u;
  29. sz[u] = 1;
  30. }
  31. }
  32.  
  33. int findSet(int u) {
  34. if (p[u] == u) return u;
  35. return p[u] = findSet(p[u]);
  36. }
  37.  
  38. bool unionSet(int u, int v) {
  39. u = findSet(u);
  40. v = findSet(v);
  41. if (u == v) return false;
  42. if (sz[u] < sz[v]) swap(u, v);
  43. p[v] = u;
  44. sz[u] += sz[v];
  45. return true;
  46. }
  47.  
  48. int main() {
  49. ios::sync_with_stdio(false);
  50. cin.tie(nullptr);
  51. cin >> n;
  52. for (int u = 1; u <= n; u++) cin >> w[u];
  53.  
  54. for (int u = 1; u <= n; u++) {
  55. for (int v = 1; v <= n; v++) {
  56. int w; cin >> w;
  57. edges.push_back({u, v, w});
  58. }
  59. }
  60.  
  61. // Tạo thêm một đỉnh ảo 0, có cạnh nối đến các đỉnh u từ 1 đến n
  62. // Với trọng số cạnh chính là chi phí để đào một cái giếng ở đỉnh u
  63. for (int u = 1; u <= n; u++) {
  64. edges.push_back({0, u, w[u]});
  65. }
  66.  
  67. // Tìm MST của tập đỉnh từ 0 đến n
  68. sort(edges.begin(), edges.end());
  69.  
  70. initSet();
  71.  
  72. int ans = 0;
  73. for (Edge e : edges) {
  74. if (unionSet(e.u, e.v)) ans += e.w;
  75. }
  76.  
  77. cout << ans << '\n';
  78. }
Success #stdin #stdout 0s 5288KB
stdin
4
5
4
4
3
0 2 2 2
2 0 3 3
2 3 0 4
2 3 4 0
stdout
9