본문 바로가기
알고리즘 일기/JAVA

swea_1251_하나로

by Beijing_KingGod 2020. 3. 11.

왜 못풀었는가 ? -> 완탐으로 풀려고 했음....

 

* bfs -> 간선 가중치가 0이나 1일때 최소비용 문제일때 사용.

* dfs -> N  이 1000이라서 너무 범위가 많아서 사용 X.

* 완전탐색 안되면 :DP, 그리디

* 그리디 -> 활동 선택 문제 : 회의실 배정, 냉장고 문제,,

            -> 그래프와 관련된 그리디 : prim, kruskal, dijkstra

            -> prim, kruskal -> MST

            -> dijkstra -> 어떤 정점에서 다른 정점까지의 최단 거리(비용)

 

*MST -> minimum spannig tree

*spanning tree -> 모든 정점을 연결하고, 간선의 부분들로 이루어진 집합.

                    -> tree이므로 모든 정점이 연결되고, cycle은 없다, root 개념, 조상, 자식 개념은 없다.

 

*MST 

  - Prim     : dijkstra 와 동일한 개념

  - kruskal  :  union-find 개념이용 MST  구현.

 


해결방법 : 트리구조를 만들어서 탐색을 해라.

트리 : 사이클이 없이 모든 정점 연결,,

최소신장트리 : 최소비용으로 연결되는 tree.

 


package algo;

import java.io.*;
import java.util.*;

public class Main { 
	static int N;
	static long[] mx,my;
	static long[][] graph;
	static double d;
	public static void main(String[] args)throws Exception {
		System.setIn(new FileInputStream("res/input"));
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = null;
		int T = Integer.parseInt(br.readLine());
		for(int tc = 1; tc<=T; tc++) {
			N = Integer.parseInt(br.readLine());
			mx = new long[N];
			my = new long[N];
			st = new StringTokenizer(br.readLine());
			for(int i=0; i<N; i++) {
				mx[i] = Long.parseLong(st.nextToken());
			}
			st = new StringTokenizer(br.readLine());
			for(int i=0; i<N; i++) {
				my[i] = Long.parseLong(st.nextToken());
			}
			d = Double.parseDouble(br.readLine());
			
			// 가중치 그래프 그리기!
			graph = new long[N][N];
			for(int r=0; r<N; r++) {
				for(int c = r+1; c<N; c++) {
					graph[c][r] = graph[r][c] = (mx[r]-mx[c])*(mx[r]-mx[c])+(my[r]-my[c])*(my[r]-my[c]);
				}
			}
			double ans = prim(0)*d;
			
			System.out.println("#"+tc+" "+Math.round(ans));
		}
	}
	static long prim(int start) {
		
		//MST에 들어가지 않은 녀석들.
		PriorityQueue<Edge> pq = new PriorityQueue<>();
		//모든 정점들을 다 관리...
		Edge[] dynamicGraph = new Edge[N];
		
		for(int n=0; n<dynamicGraph.length; n++) {
			dynamicGraph[n] = new Edge(n, Long.MAX_VALUE);
			if(n==start) {
				dynamicGraph[n].cost = 0;
			}
			pq.add(dynamicGraph[n]);
		}
		
		long cost = 0;
		while(!pq.isEmpty()) {
			Edge front = pq.poll();
			cost += front.cost;
			
			//자식 탐색
			for(int i=0; i<dynamicGraph.length; i++) {
				Edge child = dynamicGraph[i];
				//pq: MST에 포함되어있지 않은 정점들
				if(pq.contains(child)) {
					long tempCost = graph[front.idx][child.idx];
					if(tempCost < child.cost) {
						child.cost = tempCost;
						pq.remove(child);
						pq.offer(child);
					}
				}
			}
		}
		return cost;
	}
	static class Edge implements Comparable<Edge>{
		int idx;
		long cost;
		public Edge(int idx, long cost) {
			super();
			this.idx = idx;
			this.cost = cost;
		}
		@Override
		public int compareTo(Edge o) {
			// TODO Auto-generated method stub
			return Long.compare(this.cost, o.cost);
		}
		
	}

}

 

 

그래프 공부해야겠다...

 

댓글