티스토리 뷰

Algorithm

백준_게리맨더링_17471

Young_J 2020. 9. 9. 11:03

알고리즘

연결리스트를 만든 후

부분집합을 사용하여 구를 나누고 bfs를 돌려 연결되어 있는지 확인

연결되어 있다면 인구수의 최소값을 구함.

 

package baekjoon;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

public class 게리맨더링_17471 {
	static int arr[], N, Ans = Integer.MAX_VALUE;
	static boolean[] v;
	static ArrayList<Integer>[] list;

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		N = sc.nextInt(); // 구역의 개수

		arr = new int[N]; // 인구수

		// 각 구의 인구 수 입력
		for (int i = 0; i < N; i++) {
			arr[i] = sc.nextInt();
		}

		list = new ArrayList[N];

		for (int i = 0; i < list.length; i++) {
			list[i] = new ArrayList<Integer>();
		}

		// 각 구와 연결된 리스트 만들기
		for (int i = 0; i < N; i++) {
			int num = sc.nextInt();
			for (int j = 0; j < num; j++) {
				list[i].add(sc.nextInt() - 1);
			}
		}
		v = new boolean[N];
		for (int i = 1; i <= N / 2; i++) {
			powerSet(0, i);
		}

		System.out.println(Ans == Integer.MAX_VALUE ? "-1" : Ans);

	}

	private static void powerSet(int idx, int end) {
		if (idx == end) {
			int A = 0;
			int B = 0;
			for (int i = 0; i < v.length; i++) {
				if (v[i])
					A = i;
				else
					B = i;
			}

			if (bfs(A, new boolean[N]) && bfs(B, new boolean[N])) {

				int sumA = 0;
				int sumB = 0;

				for (int i = 0; i < arr.length; i++) {
					if (v[i])
						sumA += arr[i];
					else
						sumB += arr[i];
				}

				Ans = Math.min(Math.abs(sumA - sumB), Ans);
			}

			return;
		}

		for (int i = 0; i < arr.length; i++) {
			if (v[i])
				continue;
			v[i] = true;
			powerSet(idx + 1, end);
			v[i] = false;
		}

	}

	private static boolean bfs(int start, boolean[] check) {
		Queue<Integer> q = new LinkedList<Integer>();
		q.add(start);
		check[start] = true;
		if (v[start]) {
			while (!q.isEmpty()) {
				int num = q.poll();

				int size = list[num].size();
				for (int i = 0; i < size; i++) {
					int a = list[num].get(i);
					if (!check[a] && v[a]) {
						q.add(a);
						check[a] = true;
					}
				}

			}

			for (int i = 0; i < check.length; i++) {
				if (v[i] != check[i])
					return false;
			}

			return true;
		} else {
			while (!q.isEmpty()) {
				int num = q.poll();

				int size = list[num].size();
				for (int i = 0; i < size; i++) {
					int a = list[num].get(i);
					if (!check[a] && !v[a]) {
						q.add(a);
						check[a] = true;
					}
				}

			}

			for (int i = 0; i < check.length; i++) {
				if (v[i] == check[i])
					return false;
			}

			return true;
		}

	}

}

'Algorithm' 카테고리의 다른 글

백준_안전영역_2468  (0) 2020.09.11
백준_불_5427  (0) 2020.09.10
백준_DFS와 BFS_1260  (0) 2020.09.08
SW Expert Academy_홈 방범 서비스  (0) 2020.09.07
백준_미세먼지안녕_17144  (0) 2020.09.06
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG more
«   2025/02   »
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
글 보관함