UVa 908 - Re-connecting Computer Sites

Contents

  1. 1. Problem
  2. 2. Solution
  3. 3. Code

Problem

題目網址
中文網址

給出一開始的配線、未用到的線和新增的網路線,來計算 一開始 以及 增添新的網路線後 所需的最小成本。

Solution

利用 Kruskal’s Algorithm 即可解。

Code

UVa 908UVa 908 - Re-connecting Computer Sites
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

//C++11
#include<cstdio>
#include<algorithm>
#define MAX 1000001

struct Edge
{
int v1, v2;
int weight;
}edge[MAX];

//disjoint-set forest
int p[MAX];
inline int find(int a);
//minimum spanning tree
int kruskal(int N, int E);
int main()
{
int N;
bool first = true;
while (scanf("%d", &N) != EOF)
{
int i, a, b, w;
int old_cost = 0, new_cost;
for (i = 1; i < N; i++)
{
scanf("%d%d%d", &a, &b, &w);
old_cost += w;
}

int K, M;
scanf("%d", &K);
for (i = 0; i < K; i++)
scanf("%d%d%d", &edge[i].v1, &edge[i].v2, &edge[i].weight);

scanf("%d", &M);
for (i = 0; i < M; i++)
scanf("%d%d%d", &edge[i + K].v1, &edge[i + K].v2, &edge[i + K].weight);

new_cost = kruskal(N, K + M);

if (first)
first = false;
else
putchar('\n');
printf("%d\n%d\n", old_cost, new_cost);
}

return 0;
}
int kruskal(int N, int E)
{
int i;
//init
for (i = 0; i <= N; i++)
p[i] = i;

std::sort(edge, edge + E,
[](const Edge& a, const Edge& b)->bool{return a.weight < b.weight; }
);

int e, cost = 0;
for (i = 0, e = 0; i < E&&e < N - 1; e++, i++)
{
//判斷是否會成為環
while (find(edge[i].v1) == find(edge[i].v2))i++;

//union
p[find(edge[i].v1)] = find(edge[i].v2);

//count cost
cost += edge[i].weight;
}

return cost;
}
int find(int a)
{
return a == p[a] ? a : (p[a] = find(p[a]));
}