[백준 10423 C++][G2] 전기가 부족해

2021. 12. 8. 23:43· Coding test/Baekjoon
목차
  1. ⭐️ 난이도
  2. ⭐️ 문제
  3. ⭐️ Idea flow
  4. ⭐️ Code
  5.  
728x90

⭐️ 난이도

 

Gold 2


⭐️ 문제

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

 

10423번: 전기가 부족해

첫째 줄에는 도시의 개수 N(1 ≤ N ≤ 1,000)과 설치 가능한 케이블의 수 M(1 ≤ M ≤ 100,000)개, 발전소의 개수 K(1 ≤ K ≤ N)개가 주어진다. 둘째 줄에는 발전소가 설치된 도시의 번호가 주어진다. 셋째

www.acmicpc.net

 


⭐️ Idea flow

 

MST를 통해 풀 수 있는 문제였다.

 

그런데 왜 MST로 푸는 문제일까?

발전소(시작 지점)이 한 군데가 아니기 때문에 다른 알고리즘을 사용해야하나 고민했다.

하지만 목적지가 따로 없고, 모든 노드(도시)를 연결해야 하는 문제이므로 MST 문제라고 판단했다.

 

왜 prim 알고리즘을 사용해야 할까?

예시를 통해 문제를 시뮬레이션하면서 가중치가 적은 간선을 선택하는 동시에 발전소가 있는 도시가 서로 연결되지 않게 연결을 했다.

그랬더니 원하는 결과가 나왔다.

하지만 크루스칼 알고리즘을 사용하면 간선을 연결하면서 어떤 발전소와 연결되어 있는지 확인하기 힘들다는 단점이 있다.

반면 프림 알고리즘을 사용하면 현재까지 선택된 정점을 기준으로 주변 간선들을 확인하기 때문에 어떤 발전소와 연결되어 있는지 확인하기가 더 용이하다.

 

연결된 도시에서 발전소가 설치된 도시는 하나만 있어야 한다!

정점을 방문하면서 해당 정점(도시)가 어떤 발전소와 연결되어 있는지 확인을 해야 하나?라는 의구심이 들었다.

정점을 선택하는 과정을 겪기 전에 발전소가 있는 도시의 주변 간선을 모두 우선순위 큐에 push하는 과정을 거친다.

이후 정점을 선택하는데, 이 때 만약 해당 정점을 방문했다는 것은 곧 발전소와 연결되어 있다는 뜻이고,

MST는 사이클이 없는 그래프. 즉 Tree이기 때문에 어떤 발전소와 연결되어 있는지 따로 처리는 필요없다고 판단했다.

 

 

[전체 알고리즘]

1. input을 받으면서 정점을 잇는 간선의 정보를 변수 graph에, 발전소가 있는 도시의 정보는 변수 generator에 담는다.

2. generator를 반복문으로 돌면서 해당 도시를 방문처리하고, 해당 도시와 연결되어 있는 간선들을 우선순위 큐에 삽입한다.

3. 프림 알고리즘을 실행한다. 프림 알고리즘을 통해서 최소 비용인 간선(케이블)들을 선택할 것이다.

 

 


⭐️ Code

#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
#include <cmath>
#include <vector>
#include <queue>

#define INF 987654321;
using namespace std;

// 10423 - 전기가 부족해
int n, m, k; // 도시의 수, 케이블의 수, 발전 도시의 수
vector<vector<pair<int, int>>> graph;
vector<int> isVisited; // 정점 방문 여부 저장
vector<int> generator; // 발전소가 설치된 도시의 정보 저장

void input(){
    cin >> n >> m >> k;

    graph.assign(n + 1, vector<pair<int, int>>{});
    isVisited.assign(n + 1, false);
    generator.assign(k, 0);

    // 발전소가 설치된 도시의 번호
    for(int i = 0; i < k; i++){
        cin >> generator[i];
    }

    // 케이블 연결
    for(int i = 0; i < m; i++){
        int u, v, w;
        cin >> u >> v >> w;
        graph[u].emplace_back(v, w);
        graph[v].emplace_back(u, w);
    }
}

void setGenerator(priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>>& pq){
    // 발전소가 설치되어 있는 도시와 연결되어있는 간선의 정보를 넣는다.
    for(int i = 0; i < k; i++){
        isVisited[generator[i]] = true;
        for(int j = 0; j < graph[generator[i]].size(); j++){
            // 간선의 비용, 연결된 도시의 번호
            pq.push({graph[generator[i]][j].second, graph[generator[i]][j].first});
        }
    }
}

void prim(){
    int sum = 0;
    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;
    setGenerator(pq);

    while(!pq.empty()){
        int cost = pq.top().first;
        int cur = pq.top().second;
        pq.pop();

        if(!isVisited[cur]){
            isVisited[cur] = true;
            sum += cost;

            for(int i = 0; i < graph[cur].size(); i++){
                int next = graph[cur][i].first;
                int n_cost = graph[cur][i].second;
                if(!isVisited[next]){
                    pq.push({n_cost, next});
                }
            }
        }
    }
    cout << sum;
}

int main(){

    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

    input();
    prim();

    return 0;
}

 

 

728x90
  1. ⭐️ 난이도
  2. ⭐️ 문제
  3. ⭐️ Idea flow
  4. ⭐️ Code
  5.  
'Coding test/Baekjoon' 카테고리의 다른 글
  • [백준 2252 C++][G3] 줄 세우기
  • [백준 2056 C++][G4] 작업
  • [백준 14950 C++][G3] 정복자
  • [백준 16202 C++][G4] MST 게임
HEY__
HEY__
안녕하세요 :) 공부하며 배운 것들을 기록하기 위한 블로그입니다. 도움이 되시길 바라며 혹시 잘못된 점이 있다면 댓글 부탁드립니다! :D
250x250
HEY__
while(true) { continue; }
HEY__
전체
오늘
어제
  • 분류 전체보기 (164)
    • Spring Boot (45)
      • 스프링 입문 강의 (18)
    • AWS (8)
    • 프로젝트 (6)
    • Network (21)
    • Operating System (8)
    • Database (4)
    • ETC (2)
    • Java (3)
    • C++ (7)
    • Python (1)
    • 도서 📚 (3)
      • Effective Java (3)
    • Coding test (50)
      • Baekjoon (30)
      • Leet Code (18)
      • Programmers (2)
    • Algorithm (C++) (5)

블로그 메뉴

  • 태그
  • Github
  • 글쓰기
  • 블로그관리

공지사항

인기 글

태그

  • dispatcher servlet
  • Servlet Container
  • OS
  • CPP
  • Java
  • Baekjoon
  • Cloudfront
  • slack
  • C++
  • Spring
  • leetcode
  • programmers
  • HTTP
  • coding test
  • STL
  • kotlin
  • Algorithm
  • Network
  • aws
  • spring boot

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.0
HEY__
[백준 10423 C++][G2] 전기가 부족해
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.