r*c 크기의 체스판이 있고 n개의 룩을 놓을 수 없는 칸(룩들이 빈칸을 사이에 두고 배치되었을 때 공격 조건을 만족하면 공격 가능하다. 즉 공격 가능 여부에는 영향을 미치지 않는다.)이 있을 때 최대 룩을 몇 개 놓을 수 있는지 출력하는 문제다.


  1. n개의 룩을 받으면서 동시에 map에 -1로 기록을 해놓는다.

  2. map[i][j]가 -1이 아니면 i->j로 간선을 연결한다.(1번방법)

  3. 이분매칭


※ 맵을 만들어놓기 싫다면 1<=i<=r, 1<=j<=c 모든 간선을 연결 해 놓고 빈칸의 좌표를 입력받으며 해당 간선을 지워도 된다(2번방법). 속도는 동일하지만 메모리는 범위가 300까지밖에 안되기 때문에 2번 방법이 훨씬 적게든다.



<1번방법 코드>

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
#include <stdio.h>
#include <iostream>
#include <vector>
using namespace std;
 
int r, c, n, x, y, map[301][301];
vector<int> v[301];
vector<int> p(301-1);
vector<bool> ch(301);
 
int dfs(int x) {
    if (x == -1return 1;
    for (auto i : v[x]) {
        if (ch[i]) continue;
        ch[i] = 1;
        if (dfs(p[i])) {
            p[i] = x;
            return 1;
        }
    }
    return 0;
}
 
int main() {
    scanf("%d%d%d"&r, &c, &n);
    while (n--) {
        scanf("%d%d"&x, &y);
        map[x][y] = -1;
    }
    for (int i = 1; i <= r; i++for (int j = 1; j <= c; j++)
        if (!map[i][j]) v[i].push_back(j);
    int ans = 0;
    for (int i = 1; i <= r; i++if (v[i].size()) {
        fill(ch.begin(), ch.end(), false);
        ans += dfs(i);
    }
    printf("%d\n", ans);
    return 0;
}

cs


<2번방법 코드>
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
#include <stdio.h>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
 
int r, c, n, x, y, v[301][301], p[301];
bool ch[301];
 
int dfs(int x) {
    if (x == -1return 1;
    for (int i = 1; i <= c; i++) {
        if (ch[i] || !v[x][i]) continue;
        ch[i] = 1;
        if (dfs(p[i])) {
            p[i] = x;
            return 1;
        }
    }
    return 0;
}
 
int main() {
    memset(p, -1sizeof(p));
    scanf("%d%d%d"&r, &c, &n);
    for (int i = 1; i <= r; i++for (int j = 1; j <= c; j++) v[i][j] = 1;
    while (n--) {
        scanf("%d%d"&x, &y);
        v[x][y] = 0;
    }
    int ans = 0;
    for (int i = 1; i <= r; i++) {
        memset(ch, falsesizeof(ch));
        ans += dfs(i);
    }
    printf("%d\n", ans);
    return 0;
}
cs


'BOJ' 카테고리의 다른 글

1649 택시  (1) 2017.09.06
10319 좀비 아포칼립스  (0) 2017.09.05
10026 적록색약  (0) 2017.09.01
6603 로또  (0) 2017.09.01
2644 촌수계산  (0) 2017.09.01

+ Recent posts