티스토리 뷰
1647번: 도시 분할 계획
첫째 줄에 집의 개수N, 길의 개수M이 주어진다. N은 2이상 100,000이하인 정수이고, M은 1이상 1,000,000이하인 정수이다. 그 다음 줄부터 M줄에 걸쳐 길의 정보가 A B C 세 개의 정수로 주어지는데 A번 집
www.acmicpc.net
이 문제는 MST(최소 신장(스패닝) 트리)를 이용하여 풀 수 있었다. 크루스 칼, 프림 두 개의 알고리즘으로 풀이가 가능했고 나의 경우 프림 알고리즘으로 풀었다.
문제풀이
2개의 도시로 분할해야 하므로 프림 알고리즘을 통해 MST를 만든 후 가장 비용이 높은 간선 하나를 제거하면 2개의 도시로 나눠지고 최소 비용을 구할 수 있다.
- 임의의 시작 노드를 Queue에 넣고 연결된 NodeList를 PriorityQueue에 넣는다
-> 간선의 비용으로 정렬된 값을 얻기위해 PriorityQueue를 사용한다.
- 이미 연결된 간선을 표시하기 위해 visited[]배열을 true로 기록해준다
- PriorityQueue에서 순차적으로 꺼낸 노드중 visited [노드] == false 인경우 전체 비용에 추가하고 노드를 Queue에 추가한다
- 비용에 추가하면서 비용이 가장 높은 간선하나를 마지막에 제거하기 위해 max변수에 기록한다
- 전체 노드가 연결될때 까지 반복한다
public class Ex_1647 {
static List<Node>[] list;
static boolean[] visited;
static int ans = 0;
static int n;
static int max = Integer.MIN_VALUE;
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
// 최소스패닝 트리 - 도시 분할 계획
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
n = Integer.parseInt(st.nextToken());
int m = Integer.parseInt(st.nextToken());
list = new List[n + 1];
visited = new boolean[n + 1];
for (int i = 0; i <= n; i++)
list[i] = new ArrayList<>();
while (m-- > 0) {
st = new StringTokenizer(br.readLine());
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
int w = Integer.parseInt(st.nextToken());
list[a].add(new Node(b, w));
list[b].add(new Node(a, w));
}
mts();
System.out.println(ans-max);
}
static void mts() {
PriorityQueue<Node> pq = new PriorityQueue<>();
Queue<Integer> nodeQ = new LinkedList<>();
nodeQ.add(1);//1번 노드부터 시작
List<Node> curList;
while (!nodeQ.isEmpty()) {
int cur = nodeQ.poll();
visited[cur] = true;
curList = list[cur];
for (int i = 0; i < curList.size(); i++) {
//연결되지 않은 노드라면 pq에 저장
if (!visited[curList.get(i).end]) {
pq.add(curList.get(i));
}
}
//연결되지 않은 노드중 가장 적은 비용의 간선을 연결
while (!pq.isEmpty()) {
Node tmpNode = pq.poll();
if (!visited[tmpNode.end]) {
visited[tmpNode.end] = true;
ans += tmpNode.w; //전체 비용에 추가
max = Math.max(tmpNode.w, max); //가장 큰 비용의 간선 찾음
//연결된 노드에 연결된 다른 노드 리스트 찾기위해 nodeQ에 저장
nodeQ.add(tmpNode.end);
break;
}
}
}
}
static class Node implements Comparable<Node> {
int end;
int w;
Node(int end, int w) {
this.end = end;
this.w = w;
}
@Override
public int compareTo(Node n) {
return w - n.w;
}
}
}
'CS공부 > 알고리즘&문제풀이' 카테고리의 다른 글
[프로그래머스] 2021카카오 인턴십 : 표 편집 (java) (0) | 2021.07.12 |
---|---|
[알고리즘] DP (Dynamic Programming) 동적 계획법 (0) | 2021.07.11 |
[백준 10775] 공항 (java) (0) | 2021.06.16 |
[백준 13460]구슬 탈출 2/삼성 sw역량 테스트 기출(java) (0) | 2021.06.10 |
[백준 3190]뱀/삼성 sw역량 테스트 기출(java) (0) | 2021.06.08 |
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- Spring
- 분리 집합
- BFS
- JavaScript
- 백준
- 완전탐색
- 자바
- java
- DP
- git
- dfs
- MST
- Oracle
- sockjs
- 삼성 sw역량테스트
- Heap
- 알고리즘
- Stomp
- 프로그래머스
- 채팅
- websocket
- 정렬
- SWEA
- 최소 스패닝 트리
- OS
- 삼성 sw역량 테스트
- 운영체제
- 코딩테스트
- programers
- Baekjoon
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
글 보관함