백준 17398 (C++) 통신망 분할
728x90
SMALL

https://www.acmicpc.net/problem/17398

 

17398번: 통신망 분할

첫 번째 줄에는 통신탑의 개수인 자연수 N, 통신탑 사이의 연결의 개수인 자연수 M, 통신망 연결 분할 횟수인 자연수 Q가 공백으로 구분되어 주어진다. (1 ≤ N ≤ 100,000, 1 ≤ M ≤ 100,000, 1 ≤ Q 

www.acmicpc.net

 

 

 

 

 

 

아이디어

union find인데 제거할 때 나오는 비용을 세는 대신,

전부 분리한 다음 분리하지 않을 간선만 이은 채로 union을 전부 돌면 된다.

 

전부 서로소 집합인 상태에서 끊지 않을 간선을 제외한 노드들(예제에서는 1,2)을 union할때와

이후 답을 찾기위한 union은 같으나 후자에서는 부모노드 확인과정을 거친 후 비용을 곱해서 저장해야 한다.

 

아이디어는 빨리 떠올렸는데 구현에서 자잘한 실수가 많아 여러번의 제출을 걸쳐 AC를 받은 문제

 

 

 

728x90

 

 

코드

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
using ll = long long;
const int MAX = 1e6;
int n,m,q;
int Parent[MAX]; // Parent[node] == parent of node
int cost[MAX];
int elem[MAX];
ll ans = 0;
vector<pair<int, int>> c; // 연결노드 저장
vector<int> unc;
bool connect[MAX] = {false, };

int getParent(int n1) {
    if (Parent[n1] == n1) return n1;
    else return Parent[n1] = getParent(Parent[n1]);
}
void unionParent(int n1, int n2) {
    n1 = getParent(n1);
    n2 = getParent(n2);
    if (n1 != n2) {
        Parent[n2] = n1;
        cost[n1] += cost[n2];
    }
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cin >> n >> m >> q;
    
    for (int i = 1; i <= n; i++) {
        Parent[i] = i;
        cost[i] = 1;
    }
    for (int i = 0; i < m; i++) { // 연결할 간선
        int a,b;
        cin >> a >> b;
        c.push_back({a,b});
        connect[i] = true;
    }
    for (int i = 0; i < q; i++) { // 연결 끊을 간선
        int a;
        cin >> a;
        unc.push_back(a-1);
        connect[a-1] = false;
    }
    for (int i = 0; i < m; i++) { // 끊을 간선이 아니라면 union
        if (!connect[i]) continue;
        unionParent(c[i].first, c[i].second);
    }
    for (int i = q-1; i >= 0; i--) {
        int seq_to_connect = unc[i]; // 4 2 3
        auto node_to_connect = c[seq_to_connect];
        int u = getParent(node_to_connect.first);
        int v = getParent(node_to_connect.second);
        if (u != v) {
            ans += cost[u] * cost[v];
        }
        unionParent(u, v);
    }
    cout << ans;
    return 0;
}

 

 

 

728x90
LIST

'PS > BOJ' 카테고리의 다른 글

백준 11025 (C++) 요세푸스 문제 3  (0) 2021.10.09
백준 17498 (C++) 폴짝 게임  (2) 2021.10.06
백준 14938 (C++) 서강그라운드  (0) 2021.09.30
백준 20044 (C++) Project Teams  (0) 2021.09.30
백준 1931 (C++) 회의실 배정  (0) 2021.09.30