[BOJ] 2463 - 비용
풀이
문제를 읽자 마자 생각난 것은 바로 MST였다.
간선의 총 합을 구해두고, MST를 만들면서 연결하는 간선을 총합에서 빼고, 연결되는 두 연결그래프가 서로 연결되는 경우의 수만큼 그 합을 곱하여 MOD연산한 값을 더하면서 값을 구하면 되지 않을까?
그런데 계산을 해보니 이상한 값이 나왔다. 문제를 잘못 이해한 것 같다.
그래서 이런 저런 고민을 했는데… 문제를 푼 지 워낙 오래되어 기억은 잘 나지 않고..
어쨌든 결론을 말하자면 위의 방법대로 MST를 만드는 것은 같지만, PQ를 최대힙으로 바꾸어 만들면 되는 것이었다.
기존 MST아이디어에 살짝의 변형을 하면 된달까..
소스코드
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
#include <bits/stdc++.h>
#define MOD 1000000000
using namespace std;
typedef tuple<int, int, int> T;
typedef long long ll;
priority_queue<T> pq;
ll parent[100005], cnt[100005];
ll find(ll x) {
if (parent[x] == 0) return x;
return parent[x] = find(parent[x]);
}
void merge(ll x, ll y) {
if (find(x) == find(y)) return;
cnt[find(y)] += cnt[find(x)];
parent[find(x)] = find(y);
find(x);
}
int main(void) {
ll sum = 0, ans = 0, n, m;
scanf("%lld %lld", &n, &m);
fill(cnt, cnt + n + 1, 1);
for (ll i = 0; i < m; i++) {
ll x, y, w;
scanf("%lld %lld %lld", &x, &y, &w);
pq.push({ w, x, y });
sum += w;
}
while (!pq.empty()) {
ll x = get<1>(pq.top()), y = get<2>(pq.top()), w = get<0>(pq.top());
pq.pop();
if (find(x) != find(y)) {
ans = (ans + (((cnt[find(x)] * cnt[find(y)]) % MOD) * sum) % MOD) % MOD;
merge(x, y);
}
sum -= w;
}
printf("%lld\n", ans);
return 0;
}
This post is licensed under CC BY 4.0 by the author.
Comments powered by Disqus.