본문 바로가기

BOJ 1647번 : 도시 분할 계획 본문

BOJ

BOJ 1647번 : 도시 분할 계획

00rigin 2022. 4. 7. 16:51

간선의 cost 합을 최소화 하고, 각 집 사이에 경로가 항상 존재해야 한다는 조건이므로 MST를 사용하는 문제이다.

https://00rigin.tistory.com/59

 

MST (Minimum Spanning Tree) 최소 신장 트리

MST 즉 최소신장트리 (최소 스패닝 트리)는 간선에 weight가 있는 그래프를 tree로 만들어 문제를 해결할때 유용하게 사용할 수 있다. 그래프를 최소 비용 간선을 가진 tree로 만드는 방법을 MST 라고

00rigin.tistory.com

단, 조건은 마을을 2개로 만들면서, 도로의 유지비를 최소화 해야하는 것이다.

따라서, MST로 마을을 재구성 한 후에, 가장 도로 유지비가 비싼 집 하나를 정하고, 그 집을 2번째 마을로 설정한다.

이렇게 할 경우, 두개의 마을이 생기면서 가장 비싼 도로가 하나 사라져 문제의 조건을 만족 할 수 있다.

 

<소스코드>

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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#include<iostream>
#include<string>
#include<algorithm>
#include<cstring>
#include<queue>
#include<stack>
#include<vector>
#include<cmath>
#include<bitset>
 
using namespace std;
 
typedef long long ll;
typedef pair<intint> pii;
typedef pair<ll, ll> pll;
 
struct edge{
    int a;
    int b;
    int c;
};
 
int n,m;
vector<edge> v;
 
bool operator < (edge a, edge b){ // 우리가 만든 struct를 사용하는 템플릿에 대해 대소 비교를 하기 위해서 오버로딩
    if(a.c < b.c){
        return true;
    }
    else{
        return false;
    }
}
 
int parent[100001]; // 대장 내 노드의 대장을 저장함.
// parent[2] = 1 , Parent[3] = 1 이면 노드 1,2,3은 같은 그래프
 
int get_pa(int x){
    if(parent[x] == x){ // 내가 대장
        return x;
    }
    else// 내가 대장이 아닐 경우 재귀 돌아서 대장을 찾을때 까지 가서 대장을 찾음.
        parent[x] = get_pa(parent[x]); // 이렇게 안할 경우 같은 그래프임에도 대장이 다를 수 있음. 중요한 부분.
        // 재귀로 여기서 덮어 씌워놔야 다른 곳에서 재귀를 계속 안돌고 적은 시간내에 덮어쓴 값을 바탕으로 빠르게 대장 을 알 수 있음
        return parent[x];
        
        // return get_pa(parent[x]);
        // 이렇게 할 경우 시간초과가 남.
    }
}
 
void Union(int a, int b){ // 대장을 작은 놈으로 바꿔줘서 가은 그래프로 보이게 함
    
    if(a<b){
        parent[b] = a;
    }
    else{
        parent[a] = b;
    }
}
 
 
int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    
    cin>>n>>m;
    
    for(int i = 1; i<=n; i++){
        parent[i] = i;
    }
    
    for(int i = 0; i<m; i++){
        int a,b,c;
        cin>>a>>b>>c;
        edge e;
        e.a = a;
        e.b = b;
        e.c = c;
        v.push_back(e);
    }
    
    sort(v.begin(), v.end());
    
    int ans = 0;
    int las = 0;
    for(int i = 0; i<m; i++){
        int a,b,c;
        a = v[i].a;
        b = v[i].b;
        c = v[i].c;
        
        int ap = get_pa(a);
        int bp = get_pa(b);
        if(ap!=bp){ //a와 b가 같은 그래프가 아니면
            ans+=c;
            Union(ap,bp); // 하나의 그래프로 합쳐줌
            las = c;
        }
    }
    ans = ans - las;
    cout<<ans<<endl;
}
 
cs

<문제>

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

 

'BOJ' 카테고리의 다른 글

BOJ 2798 블랙잭  (0) 2023.08.08
BOJ 11657번 : 타임머신  (0) 2022.04.05
BOJ 1504번 : 특정한 최단 경로  (0) 2022.04.02
BOJ 1753번 : 최단경로  (0) 2022.03.30
BOJ 13975번 : 파일 합치기3  (0) 2022.03.26
Comments