문제 풀이
모든 두 집 쌍에 대해서 불이 켜진 길로만 서로를 왕래할 수 있도록 해야 하며, 위 조건을 지키면서 절약할 수 있는 최대 액수를 구하는 문제입니다.
모든 두 집 쌍에 대해서 가로등을 켜면서(연결하면서) 최소의 비용으로 만들고 싶다면 MST를 구하라는 문제입니다.
그런데 절약할 수 있는 최대 액수를 물었으므로 [전체의 비용 - MST를 만드는 비용 = 최대 액수]로 구해주면 됩니다.
최종 비용을 계산할 때 보통은 최소의 비용을 구하라고 하지만 반대로 얼마큼 절약할 수 있는지를 물어보는 문제였습니다.
소스 코드
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
const int MAX = 200001;
int parent[MAX];
vector<pair<int, pair<int, int> > > edges;
int m, n, totalCost;
void input()
{
edges.clear();
totalCost = 0; // 전체 비용
for (int i = 0; i < n; i++)
{
int x, y, z;
cin >> x >> y >> z;
totalCost += z;
edges.push_back({ z, {x,y} });
}
sort(edges.begin(), edges.end());
for (int i = 1; i <= m; i++) parent[i] = i;
}
int findParent(int x)
{
if (x == parent[x]) return x;
return parent[x] = findParent(parent[x]);
}
void unionParent(int a, int b)
{
a = findParent(a);
b = findParent(b);
if (a < b) parent[b] = a;
else parent[a] = b;
}
void kruskal()
{
int size = static_cast<int>(edges.size());
int useCost = 0; // MST 만드는 비용
for (int i = 0; i < size; i++)
{
int cost = edges[i].first;
int a = edges[i].second.first;
int b = edges[i].second.second;
if (findParent(a) != findParent(b))
{
unionParent(a, b);
useCost += cost;
}
}
cout << totalCost - useCost << endl;
}
void solve()
{
while (true)
{
cin >> m >> n;
if (m == 0 && n == 0) break;
input();
kruskal();
}
}
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
solve();
return 0;
}
'Algorithm' 카테고리의 다른 글
[백준 16202] MST 게임 (0) | 2021.11.21 |
---|---|
[백준 13905] 세부 (0) | 2021.11.20 |
[백준 4386] 별자리 만들기 (0) | 2021.11.19 |
[백준 1922] 네트워크 연결 (0) | 2021.11.19 |
[백준 1647] 도시 분할 계획 (0) | 2021.11.18 |