ν‹°μŠ€ν† λ¦¬ λ·°

πŸ”Ž ν”„λ¦Ό μ•Œκ³ λ¦¬μ¦˜μ΄λž€?

  : κ°€μ€‘μΉ˜κ°€ μžˆλŠ” 무ν–₯(λ°©ν–₯X) κ·Έλž˜ν”„μ˜ μ΅œμ†Œ λΉ„μš© μ‹ μž₯ 트리(MST)λ₯Ό μ°ΎλŠ” μ•Œκ³ λ¦¬μ¦˜

 

ν”„λ¦Ό μ•Œκ³ λ¦¬μ¦˜μ€ MST(μ΅œμ†Œμ‹ μž₯트리, Minimum Spanning Tree)λ₯Ό κ΅¬ν˜„ν•˜λŠ” ν•œ λ°©λ²•μœΌλ‘œ λ‹€μ΅μŠ€νŠΈλΌ(Dijkstra) μ•Œκ³ λ¦¬μ¦˜κ³Ό μœ μ‚¬ν•˜κ²Œ λ™μž‘ν•œλ‹€. 

Spanning Tree λž€ κ·Έλž˜ν”„ 쀑 λͺ¨λ“  정점이 κ°„μ„ μœΌλ‘œ μ—°κ²°λ˜μ–΄ μžˆμœΌλ©΄μ„œ 싸이클이 μ—†λŠ” κ·Έλž˜ν”„λ₯Ό μ˜λ―Έν•œλ‹€.

 

Prim μ•Œκ³ λ¦¬μ¦˜μ€ μ‹œμž‘ μ •μ μ—μ„œλΆ€ν„° μΆœλ°œν•΄μ„œ μ‹ μž₯트리 집합을 λ‹¨κ³„μ μœΌλ‘œ ν™•μž₯ν•΄λ‚˜κ°€λŠ” 방법이닀.

즉, 간선을 μ •λ ¬ν•˜μ§€ μ•Šκ³  ν•˜λ‚˜μ˜ μ •μ μ—μ„œ μ‹œμž‘ν•˜μ—¬ 트리λ₯Ό ν™•μž₯ν•΄ λ‚˜κ°€λŠ” μ•Œκ³ λ¦¬μ¦˜μ΄λ‹€.

 

πŸ’‘ μ•Œκ³ λ¦¬μ¦˜

1. κ·Έλž˜ν”„μ—μ„œ μ‹œμž‘ 정점을 선택

    μ‹œμž‘ λ‹¨κ³„μ—μ„œλŠ” μ‹œμž‘ μ •μ λ§Œμ΄ MST 집합에 ν¬ν•¨λœλ‹€.

2. μ„ νƒν•œ 정점에 λΆ€μ†λœ λͺ¨λ“  κ°„μ„  μ€‘ κ°€μ€‘μΉ˜κ°€ κ°€μž₯ μž‘μ€ κ°„μ„  μ—°κ²°ν•˜μ—¬ 트리 ν™•μž₯.

3. 이전에 μ„ νƒν•œ 정점과 μƒˆλ‘œ ν™•μž₯된 정점에 λΆ€μ†λœ λͺ¨λ“  κ°„μ„  쀑 κ°€μ€‘μΉ˜κ°€ κ°€μž₯ μž‘μ€ κ°„μ„  μ‚½μž…

    (μ΄λ•Œ, μ‚¬μ΄ν΄μ„ ν˜•μ„±ν•˜λŠ” μ•ŠλŠ” κ°€μž₯ μž‘μ€ 간선을 선택)

4. κ·Έλž˜ν”„μ— n-1개의 간선을 μ‚½μž…ν•  λ•ŒκΉŒμ§€ 3.반볡.

5. κ·Έλž˜ν”„μ˜ 간선이 n-1κ°œκ°€ 되면 μ΅œμ†Œ λΉ„μš© μ‹ μž₯ 트리(MST) μ™„μ„±.

 

각 정점듀은 μΈμ ‘ν•œ 정점 쀑 μ΅œμ†Œ λΉ„μš©μœΌλ‘œ 이동가λŠ₯ν•œ 정점을 μ„ νƒν•˜μ—¬ μΆ”κ°€ν•œλ‹€.

μš°μ„ μˆœμœ„ 큐λ₯Ό μ΄μš©ν•˜μ—¬ μž„μ˜μ˜ 정점뢀터 μΈμ ‘ν•œ 정점을 거리λ₯Ό κΈ°μ€€μœΌλ‘œ μ •λ ¬ν•œλ‹€.

μ΅œμ†Œ 거리의 정점을 κΊΌλ‚΄μ„œ λ‹€μ‹œ μΈμ ‘ν•œ 정점을 λ„£κ³  μ •λ ¬ν•œλ‹€.

μœ„μ˜ 과정을 λ°˜λ³΅ν•œλ‹€.

 

 

πŸ’‘ μ‹œκ°„ λ³΅μž‘λ„

 - μš°μ„  μˆœμœ„ 큐 = O(E * log V)

 - 인접 ν–‰λ ¬ = O(V^2)

* V = μ •μ μ˜ 수, E = κ°„μ„ (λ…Έλ“œ)의 수

 

 

πŸ“ŒJAVA μ½”λ“œ

 

public static class Edge implements Comparable<Edge>{
	int v; // μ§„μž…ν•˜λŠ” 정점
	int w; // κ°€μ€‘μΉ˜
	Edge(int vertex, int weight) {
		this.v = vertex;
		this.w = weigth;
	}
	@Override
	public int compareTo(Edge e) {
		return this.w - e.w;
	}
}
static Edge eList[] = new Edge[vNum+1];
public static int prim(int sV) {
	PriorityQueue<Edge> pQ = new PriorityQueue<>();
	pQ.add(new Edge(sV, 0)); // μ‹œμž‘ 정점 μ €μž₯
	boolean visited[] = new boolean[vNum+1]; // ν•΄λ‹Ή 정점을 κ°„μ„ μœΌλ‘œ μ—°κ²°ν•΄μ€¬λŠ”μ§€ 확인
	Edge e;
	int totW = 0;
	while(!pQ.isEmpty()) {
		e = pQ.remove(); // κ°„μ„ 
		if(!visited[e.v]) { // λ°©λ¬Έ μœ λ¬΄μ— 따라 κ·Έλž˜ν”„μ— 사이클이 μƒκΈ°λŠ”μ§€κ°€ κ²°μ •
			visited[e.v] = true;
			totW += e.w;
			for(Edge next : eList[e.v])
				if(!visited[next.v])
					pQ.add(next); // λ°©λ¬Έν•˜μ§€ μ•Šμ€ ν•΄λ‹Ή μ •μ μœΌλ‘œ λΆ€μ†λœ κ°„μ„  큐에 μ €μž₯
		}
	}
	return totW; // MST κ°€μ€‘μΉ˜ ν•©
}
μ΅œκ·Όμ— 올라온 κΈ€
Total
Today
Yesterday