1647번: 도시 분할 계획
첫째 줄에 집의 개수N, 길의 개수M이 주어진다. N은 2이상 100,000이하인 정수이고, M은 1이상 1,000,000이하인 정수이다. 그 다음 줄부터 M줄에 걸쳐 길의 정보가 A B C 세 개의 정수로 주어지는데 A번 집
www.acmicpc.net
크루스칼 알고리즘과 프림 알고리즘 둘 다 사용 가능합니다.
MST에서 추가된 조건은 도시가 두 개로 분할된다는 점입니다.
노드의 갯수가 N인 그래프에서 MST는 N - 1개의 간선을 선택합니다.
크루스칼 알고리즘으로는 N - 2개의 간선을 선택해주면 도시는 두개로 분할되고,
프림 알고리즘으로는 한 정점을 기준으로 N - 1개의 간선을 골라주면서 그 중 max간선을 뺀 값이 답입니다.
[Kruskal]
| 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 | #include <iostream> #include <algorithm> #include <vector> using namespace std; typedef struct Point {     int u;     int v;     int w; }; vector<Point> list; int parent[100001]; int N, M, ans, cnt; bool cmp(Point a, Point b) {     if (a.w < b.w) return true;     else return false; } int find(int v) {     if (parent[v] == v) return v;     return parent[v] = find(parent[v]); } void Union(int x, int y, int w) {     int a = find(x);     int b = find(y);     if (a == b) return;     parent[b] = a;     ans += w;     cnt++; } void func() {     for (int i = 0; i < M; i++) {         int u = list[i].u;         int v = list[i].v;         int w = list[i].w;         Union(u, v, w);         if (cnt == N - 2) break;     }     cout << ans << '\n'; } void init() {     for (int i = 1; i <= N; i++) {         parent[i] = i;     } } void input() {     int u, v, w;     cin >> N >> M;     for (int i = 0; i < M; i++) {         cin >> u >> v >> w;         list.push_back({ u, v, w });     }     init();     sort(list.begin(), list.end(), cmp); } int main() {     cin.tie(NULL); cout.tie(NULL);     ios::sync_with_stdio(false);     input();     func();     return 0; } | cs | 
[Prim]
| 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 | #include <iostream> #include <vector> #include <queue> #define max(a, b) {a > b ? a : b} using namespace std; vector<pair<int, int> > list[100001]; bool visit[100001]; int N, M, ans, cnt; void func() {     priority_queue<pair<int, int> > q;     int maxcost = 0;     visit[1] = true;     for (int i = 0; i < list[1].size(); i++) {         q.push({ -list[1][i].second, list[1][i].first });     }     while (!q.empty()) {         int x = q.top().second;         int w = -q.top().first;         q.pop();         if (visit[x]) continue;         visit[x] = true;         maxcost = max(maxcost, w);         ans += w;         cnt++;         if (cnt == N - 1) break;         for (int i = 0; i < list[x].size(); i++) {             int next = list[x][i].first;             int nextw = list[x][i].second;             q.push({ -nextw, next });         }     }     cout << ans - maxcost << '\n'; } void input() {     int u, v, w;     cin >> N >> M;     while (M--) {         cin >> u >> v >> w;         list[u].push_back({ v,w });         list[v].push_back({ u,w });     } } int main() {     cin.tie(NULL); cout.tie(NULL);     ios::sync_with_stdio(false);     input();     func();     return 0; } | cs | 
'algorithm > MST' 카테고리의 다른 글
| boj 1922 네트워크 연결 (0) | 2021.03.19 | 
|---|---|
| boj 1197 최소 스패닝 트리 (0) | 2021.03.18 |