카테고리 없음

백준 1922 / 네트워크 연결

행복한 토마토 2024. 12. 3. 16:37

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

 

 

정점 위주 : 크루스칼 (유니온파인드 + pq로 노드 정렬)

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

public class 네트워크연결 {
	static class Node{
		int a;
		int b;
		int c;
		Node(int a, int b, int c){
			this.a = a;
			this.b = b;
			this.c = c;
		}
	}
	static int N, M, result;
	static int[] parent, rank;
	
	public static void main(String[] args) throws Exception{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st;
		PriorityQueue<Node> pq = new PriorityQueue<>((o1,o2) -> (o1.c-o2.c));
		N = Integer.parseInt(br.readLine());
		parent = new int[N+1];
		rank = new int[N+1];
		for(int i = 1; i<=N; i++) {
			parent[i] = i;
			rank[i] = 1;
		}
		M = Integer.parseInt(br.readLine());
		for(int i = 0; i < M; i++) {
			st = new StringTokenizer(br.readLine());
			int a = Integer.parseInt(st.nextToken());
			int b = Integer.parseInt(st.nextToken());
			int c = Integer.parseInt(st.nextToken());
			pq.add(new Node(a,b,c));
		}
		result = 0;
		int size = pq.size();
		for(int i = 0; i < size; i++) {
			Node now = pq.poll();
			union(now.a, now.b, now.c);
		}
		System.out.println(result);
//		System.out.println(Arrays.toString(parent));
	}

	private static void union(int a, int b, int c) {
		int pa = find(a);
		int pb = find(b);
		if(find(pa)==find(pb)) return;
		if(rank[pa]<rank[pb]) {
			rank[pb]+=rank[pa];
			parent[pa] = pb;
		}else {
			rank[pa]+=rank[pb];
			parent[pb] = pa;
		}
		result += c;
	}

	private static int find(int a) {
		if(parent[a]==a) return a;
		return parent[a]=find(parent[a]);
	}
}

 

 

간선 위주 : 프림 (연결리스트로 정점들을 간선위주로 정렬), bfs탐색과 유사한 방법

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

public class 네트워크연결 {
	
	static class Edge{
		int to;
		int weight;
		Edge(int to, int weight){
			this.to = to;
			this.weight = weight;
		}
	}
	static int N, M, result;
	static int[] parent, rank;
	
	public static void main(String[] args) throws Exception{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st;
		N = Integer.parseInt(br.readLine());
		M = Integer.parseInt(br.readLine());
		ArrayList<Edge>[] list = new ArrayList[N+1];
		for(int i = 1; i <= N; i++) {
			list[i] = new ArrayList<>();
		}
		for(int i = 0; i < M; i++) {
			st = new StringTokenizer(br.readLine());
			int a = Integer.parseInt(st.nextToken());
			int b = Integer.parseInt(st.nextToken());
			int c = Integer.parseInt(st.nextToken());
			
			list[a].add(new Edge(b, c));
			list[b].add(new Edge(a, c));
		}
		
		boolean[] visited = new boolean[N+1];
		PriorityQueue<Edge> pq = new PriorityQueue<>((o1,o2)->(o1.weight-o2.weight));
		
		visited[1] = true; //1번 정점부터 시작
		for(Edge e : list[1]) {
			pq.offer(e);
		}
		
		int result = 0;
		int cnt = 1; //연결된 정점의 수
		
		while(!pq.isEmpty() && cnt<N) {
			Edge curr = pq.poll();
			
			if(visited[curr.to]) continue;
			
			visited[curr.to] = true;
			result += curr.weight;
			cnt++;
			
			for(Edge next : list[curr.to]) {
				if(!visited[next.to]) {
					pq.offer(new Edge(next.to, next.weight));
				}
			}
		}
		System.out.println(result);
		
	}
}