UVa11631 - Dark Roads(Kruskal)

題目大意

Byteland 這座城市想要節省電費,因此想要在晚上把路燈給關掉,每一公尺就需要花一塊錢,但是要是整座城市都沒有路燈就太可怕了!於是 Byteland 折衷,她希望可以有一個明亮的路徑通往到每一個道路上,因此他想問說,如果只有一條明亮的路徑並且可以通往到每個道路上,那我將其他燈都關掉可以省下多少成本

題目連結

重點觀念

分析

  • 只要看懂題目大意後就會知道,其實是一個最小生成樹,只要讓每一條路可以抵達其他路即可。

參考連結

UVa 11631 - Dark Roads

題目程式碼

會在下面放一些簡單註解,供大家學習時參考。

關於 kruskal 詳解請參考 Kruskal by 大衞的筆記

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
#include <iostream>
#include <bits/stdc++.h>
#define LOCAL
#define MAXN 200020
#define int long long
using namespace std;
int n, m;
int a, b, c;
int p[MAXN];

struct edge{
int u, v, c;
edge(){
u = 0, v = 0, c = 0;
}
edge(int _u, int _v, int _c){
u = _u, v = _v, c = _c;
}
bool operator < (const edge& other) const{
return c < other.c;
}
};
vector<edge> node;
vector<edge> remain; //放入沒有被用入 edge,記錄省下成本

int find_root(int x){
//cout << "find_root " << x << "\n";
if(p[x] != x) return p[x] = find_root(p[x]);
return x;
}

int32_t main()
{
#ifdef LOCAL
freopen("in1.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif // LOCAL

while(cin >> n >> m && (n+m) != 0){
node.clear();
remain.clear();
for(int i = 0; i < n; i++) p[i] = i;

for(int i = 0; i < m; i++){
cin >> a >> b >> c;
node.push_back({a,b,c});
}
sort(node.begin(), node.end());

for(edge it: node){
//cout << it.u << " " << it.v << " " << it.c << "\n";
//cout << p[3] << " " << p[4] << "\n";
int pu = find_root(it.u);
int pv = find_root(it.v);
if(pu != pv) p[pv] = pu;
else remain.push_back(it); //紀錄沒被用到的邊

}

int ans = 0;
for(edge it: remain) ans += it.c; //計算總和
cout << ans << "\n";


}
return 0;
}
  • 版權聲明: 本部落格所有文章除有特別聲明外,均採用 Apache License 2.0 許可協議。轉載請註明出處!
  • © 2020-2024 John Doe
  • Powered by Hexo Theme Ayer
  • PV: UV: