알고리즘68 :: BOJ_17471_게리맨더링
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.StringTokenizer;
public class 게리맨더링 {
static int n;
static int[] people;
static int[][] map;
static ArrayList<Integer> team1 = new ArrayList<>();
static ArrayList<Integer> team2 = new ArrayList<>();
static int[] team1_arr;
static int[] team2_arr;
static int ans =Integer.MAX_VALUE;
static void T1DFS(int nn) {
for(int i=1; i<=n; i++) {
if(map[nn][i]==1 && team1_arr[i]==1) {
team1_arr[i]=0;
T1DFS(i);
}
}
}
static void T2DFS(int nn) {
for(int i=1; i<=n; i++) {
if(i==nn)continue;
if(map[nn][i]==1 && team2_arr[i]==1) {
team2_arr[i]=0;
T2DFS(i);
}
}
}
static void DFS(int nn) {
if(nn==n+1) {
if(team1.size()==n || team2.size()==n) return ;
team1_arr = new int[n+1];
team1_arr[team1.get(0)] = 0; //처음 들어가는 노드는 0
for(int i=1; i<team1.size(); i++) {
team1_arr[team1.get(i)] = 1; //나눈 팀 정보 배열에 저장
}
boolean team1_flag = true;
T1DFS(team1.get(0)); //연결되었는지 확인
for(int i=1; i<=n; i++)
if(team1_arr[i]==1) //1이 있다면 연결된것이 아님
team1_flag = false;
team2_arr = new int[n+1];
team2_arr[team2.get(0)] = 0;
for(int i=1; i<team2.size(); i++)
team2_arr[team2.get(i)] = 1;
boolean team2_flag = true;
T2DFS(team2.get(0));
for(int i=1; i<=n; i++)
if(team2_arr[i]==1)
team2_flag = false;
if(team1_flag == true && team2_flag ==true) {
int sum1 = 0;
for(int i=0; i<team1.size(); i++) {
sum1+=people[team1.get(i)];
}
int sum2 = 0;
for(int i=0; i<team2.size(); i++) {
sum2+=people[team2.get(i)];
}
if(ans>Math.abs(sum1-sum2)) ans = Math.abs(sum1-sum2);
}
}else {
team1.add(nn);
DFS(nn+1);
team1.remove(team1.size()-1);
team2.add(nn);
DFS(nn+1);
team2.remove(team2.size()-1);
}
}
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
n = Integer.parseInt(br.readLine());
people = new int[n+1];
StringTokenizer st = new StringTokenizer(br.readLine());
for(int i=1; i<=n; i++) {
people[i] = Integer.parseInt(st.nextToken());
}
map = new int[n+1][n+1];
for(int i=1; i<=n; i++) {
st = new StringTokenizer(br.readLine());
int cnt = Integer.parseInt(st.nextToken());
for(int j=1; j<=cnt; j++) {
int near = Integer.parseInt(st.nextToken());
map[i][near] = 1;
map[near][i] = 1;
}
}//end of for loop
DFS(1);
if(ans == Integer.MAX_VALUE)
System.out.println(-1);
else
System.out.println(ans);
}
}
|
cs |
게링 맨더링 문제는
1. 선거구를 나눈다.
2. 선거구가 형성될 수 있는지 확인한다. (=연결되었는지 확인한다.)
3. 형성될 수 있다면 최솟값을 구하는 문제다.
접근은 (위와 매치해서 번호를 달아두었다.)
1. 선거구를 나눌때 ArrayList 두개를 사용했다. 어레이 리스트 두개를 이용해서 팀을 나누고 int[] 배열을 2개 만들어 줬다. int[] 배열 각각에 팀 정보를 담았다.
2. 선거구가 형성된지 아닌지 DFS를 탐색하며 확인할 수 있다. 기본 DFS 폼에서 int[] 배열에 저장된 정보가 들어가 있다면 재귀를 호출하였다. (team1_arr[i] == 1, 저장된 정보가 들어가있다면 연결된것을 의미하므로) 물론 처음에 들어갈때 int[] 배열에 저장된 정보를 0으로 바꿔줘야 한다. 시작되는 노드이므로
3. 최솟값을 매번 갱신하면 된다.
'알고리즘' 카테고리의 다른 글
알고리즘71 :: BOJ_1541_잃어버린 괄호 (0) | 2020.02.28 |
---|---|
알고리즘69 :: BOJ_13866_팀나누기 (0) | 2020.02.26 |
알고리즘66 :: BOJ_1914_하노이탑 (0) | 2020.02.24 |
알고리즘63 :: BOJ_1987_알파벳 (0) | 2020.02.24 |
알고리즘62 :: BOJ_15740_A+B - 9 (0) | 2020.02.24 |
댓글
이 글 공유하기
다른 글
-
알고리즘71 :: BOJ_1541_잃어버린 괄호
알고리즘71 :: BOJ_1541_잃어버린 괄호
2020.02.28 -
알고리즘69 :: BOJ_13866_팀나누기
알고리즘69 :: BOJ_13866_팀나누기
2020.02.26 -
알고리즘66 :: BOJ_1914_하노이탑
알고리즘66 :: BOJ_1914_하노이탑
2020.02.24 -
알고리즘63 :: BOJ_1987_알파벳
알고리즘63 :: BOJ_1987_알파벳
2020.02.24