본문 바로가기

코딩테스트 준비/PS

C++ 백준 1647 (도시 분할 계획)

백준 1647 (도시 분할 계획)

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

 

1647번: 도시 분할 계획

첫째 줄에 집의 개수 N, 길의 개수 M이 주어진다. N은 2이상 100,000이하인 정수이고, M은 1이상 1,000,000이하인 정수이다. 그 다음 줄부터 M줄에 걸쳐 길의 정보가 A B C 세 개의 정수로 주어지는데 A번

www.acmicpc.net


설명


이 문제는 MST를 찾는 문제이다. 

 

MST를 찾기 위해 크루스칼 알고리즘을 사용해야하는데 이에 대한 자세한 설명은 여기(링크)에 있다.

 

연결되어있는 여러 도시를 가장 작은 MST 두개의 그룹으로 나누는 것이 문제의 목표이다.

때문에 주어진 그래프의 MST로 찾은 후에 찾은 MST중 가중치가 가장 큰 엣지만 제거한다면 문제를 쉽게 해결할 수 있다!

 

구현


#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int p[100001];
int n;
long long ans=0;
int M = 0;
vector <pair<int, pair<int, int>>> edge;

int find(int a){
    if(p[a]==a) return a;
    return p[a]=find(p[a]);
}

int main(){
    ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
    int m;
    int count=0;
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        p[i]=i;
    }
    int a,b,c;
    for(int i=0;i<m;i++){
        cin>>a>>b>>c;
        edge.push_back({c,{a,b}});
    }
    sort(edge.begin(),edge.end());
    for(int i=0;i<edge.size();i++){
        if(count == n-1) break; // 채택한 엣지의 개수가 V-1개면 이미 MST가 완성된 것이다.
        pair<int, pair<int ,int >> temp = edge[i];
        int tmp1= find(temp.second.first);
        int tmp2 = find(temp.second.second);
        if(tmp1 == tmp2) continue;
        p[tmp2] = tmp1; //merge와 같다.
        ans+=temp.first;
        M = max(M, temp.first); // 채택된 엣지중 가장 큰 엣지의 가중치를 저장
    }
    cout<<ans-M; // 만든 MST의 엣지 합에서 가중치가 가장 큰 엣지의 가중치를 뺀다. (두개의 그룹으로 나눔) 
    return 0;
}

'코딩테스트 준비 > PS' 카테고리의 다른 글

C++ 백준 1562 (계단 수)  (0) 2021.09.03
C++ 백준 17404 (RGB거리 2)  (0) 2021.09.03
C++ 백준 1149 (RGB거리)  (0) 2021.09.03
C++ 백준 1948 (임계경로)  (2) 2021.09.02
C++ 백준 2252 (줄 세우기)  (0) 2021.08.29