www.acmicpc.net/problem/1647

 

1647번: 도시 분할 계획

첫째 줄에 집의 개수N, 길의 개수M이 주어진다. N은 2이상 100,000이하인 정수이고, M은 1이상 1,000,000이하인 정수이다. 그 다음 줄부터 M줄에 걸쳐 길의 정보가 A B C 세 개의 정수로 주어지는데 A번 집

www.acmicpc.net

크루스칼 알고리즘과 프림 알고리즘 둘 다 사용 가능합니다.

 

MST에서 추가된 조건은 도시가 두 개로 분할된다는 점입니다.

노드의 갯수가 N인 그래프에서 MST는 N - 1개의 간선을 선택합니다.

크루스칼 알고리즘으로는 N - 2개의 간선을 선택해주면 도시는 두개로 분할되고,

프림 알고리즘으로는 한 정점을 기준으로 N - 1개의 간선을 골라주면서 그 중 max간선을 뺀 값이 답입니다.

 

 

[Kruskal]

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
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
 
typedef struct Point {
    int u;
    int v;
    int w;
};
 
vector<Point> list;
int parent[100001];
int N, M, ans, cnt;
 
bool cmp(Point a, Point b) {
    if (a.w < b.w) return true;
    else return false;
}
 
int find(int v) {
    if (parent[v] == v) return v;
    return parent[v] = find(parent[v]);
}
 
void Union(int x, int y, int w) {
    int a = find(x);
    int b = find(y);
 
    if (a == b) return;
    parent[b] = a;
    ans += w;
    cnt++;
}
 
void func() {
    for (int i = 0; i < M; i++) {
        int u = list[i].u;
        int v = list[i].v;
        int w = list[i].w;
 
        Union(u, v, w);
        if (cnt == N - 2break;
    }
 
    cout << ans << '\n';
}
 
void init() {
    for (int i = 1; i <= N; i++) {
        parent[i] = i;
    }
}
 
void input() {
    int u, v, w;
    cin >> N >> M;
    for (int i = 0; i < M; i++) {
        cin >> u >> v >> w;
        list.push_back({ u, v, w });
    }
    init();
    sort(list.begin(), list.end(), cmp);
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    input();
    func();
 
    return 0;
}
cs

 

 

[Prim]

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
#include <iostream>
#include <vector>
#include <queue>
#define max(a, b) {a > b ? a : b}
using namespace std;
 
vector<pair<intint> > list[100001];
bool visit[100001];
int N, M, ans, cnt;
 
void func() {
    priority_queue<pair<intint> > q;
    int maxcost = 0;
    visit[1= true;
    for (int i = 0; i < list[1].size(); i++) {
        q.push({ -list[1][i].second, list[1][i].first });
    }
 
    while (!q.empty()) {
        int x = q.top().second;
        int w = -q.top().first;
        q.pop();
 
        if (visit[x]) continue;
        visit[x] = true;
        maxcost = max(maxcost, w);
        ans += w;
        cnt++;
        if (cnt == N - 1break;
 
        for (int i = 0; i < list[x].size(); i++) {
            int next = list[x][i].first;
            int nextw = list[x][i].second;
 
            q.push({ -nextw, next });
        }
    }
 
    cout << ans - maxcost << '\n';
}
 
void input() {
    int u, v, w;
    cin >> N >> M;
    while (M--) {
        cin >> u >> v >> w;
        list[u].push_back({ v,w });
        list[v].push_back({ u,w });
    }
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    input();
    func();
 
    return 0;
}
cs

 

'algorithm > MST' 카테고리의 다른 글

boj 1922 네트워크 연결  (0) 2021.03.19
boj 1197 최소 스패닝 트리  (0) 2021.03.18

www.acmicpc.net/problem/1922

 

1922번: 네트워크 연결

이 경우에 1-3, 2-3, 3-4, 4-5, 4-6을 연결하면 주어진 output이 나오게 된다.

www.acmicpc.net

emoney96.tistory.com/174

 

boj 1197 최소 스패닝 트리

www.acmicpc.net/problem/1197 1197번: 최소 스패닝 트리 첫째 줄에 정점의 개수 V(1 ≤ V ≤ 10,000)와 간선의 개수 E(1 ≤ E ≤ 100,000)가 주어진다. 다음 E개의 줄에는 각 간선에 대한 정보를 나타내는 세 정..

emoney96.tistory.com

위 문제와 같은 풀이방법입니다.

크루스칼과 프림 두 방법 모두 사용이 가능합니다.

 

 

[Kruskal]

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
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
 
typedef struct Point {
    int u;
    int v;
    int w;
};
 
vector<Point> list;
int parent[1001];
int N, M, ans, cnt;
 
bool cmp(Point a, Point b) {
    if (a.w < b.w) return true;
    else return false;
}
 
int find(int v) {
    if (parent[v] == v) return v;
    return parent[v] = find(parent[v]);
}
 
void Union(int x, int y, int w) {
    int a = find(x);
    int b = find(y);
 
    if (a == b) return;
    parent[b] = a;
    ans += w;
    cnt++;
}
 
void func() {
    for (int i = 0; i < M; i++) {
        int u = list[i].u;
        int v = list[i].v;
        int w = list[i].w;
 
        Union(u, v, w);
        if (cnt == N - 1break;
    }
 
    cout << ans << '\n';
}
 
void init() {
    for (int i = 1; i <= N; i++) {
        parent[i] = i;
    }
}
 
void input() {
    int u, v, w;
    cin >> N >> M;
    init();
    for (int i = 0; i < M; i++) {
        cin >> u >> v >> w;
        list.push_back({ u,v,w });
    }
    sort(list.begin(), list.end(), cmp);
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    input();
    func();
 
    return 0;
}
cs

 

 

[Prim]

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
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
 
vector<pair<intint> > list[1001];
bool visit[1001];
int N, M, ans, cnt;
 
void func() {
    priority_queue<pair<intint> > q;
    visit[1= true;
    for (int i = 0; i < list[1].size(); i++) {
        q.push({ -list[1][i].second, list[1][i].first });
    }
 
    while (!q.empty()) {
        int x = q.top().second;
        int w = -q.top().first;
        q.pop();
 
        if (visit[x]) continue;
        visit[x] = true;
        ans += w;
        cnt++;
        if (cnt == N - 1break;
        for (int i = 0; i < list[x].size(); i++) {
            int next = list[x][i].first;
            int nextw = list[x][i].second;
 
            q.push({ -nextw, next });
        }
    }
 
    cout << ans << '\n';
}
 
void input() {
    int u, v, w;
    cin >> N >> M;
    while (M--) {
        cin >> u >> v >> w;
        list[u].push_back({ v,w });
        list[v].push_back({ u,w });
    }
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    input();
    func();
 
    return 0;
}
cs

 

'algorithm > MST' 카테고리의 다른 글

boj 1647 도시 분할 계획  (0) 2021.03.19
boj 1197 최소 스패닝 트리  (0) 2021.03.18

www.acmicpc.net/problem/1197

 

1197번: 최소 스패닝 트리

첫째 줄에 정점의 개수 V(1 ≤ V ≤ 10,000)와 간선의 개수 E(1 ≤ E ≤ 100,000)가 주어진다. 다음 E개의 줄에는 각 간선에 대한 정보를 나타내는 세 정수 A, B, C가 주어진다. 이는 A번 정점과 B번 정점이

www.acmicpc.net

최소 스패닝 트리(MST)의 기본 연습문제입니다.

크루스칼 알고리즘과 프림 알고리즘 둘 다 사용하였습니다.

 

크루스칼 알고리즘은 가중치가 낮은 순으로 간선을 골라주시면 되는데 사이클 방지를 위해 Union-find를 이용합니다.

뽑은 간선의 두 정점을 union-find로 이어주고 parent를 같게합니다.

그 다음에 뽑은 간선의 두 정점의 parent가 같으면 사이클이 발생하므로 제외시켜주는 방식입니다.

 

프림 알고리즘은 한 정점을 임의로 정하여 bfs와 비슷한 방식으로 순회하는데

방문한 정점에 연결된 간선 모두를 우선순위 큐에 넣고

다음 방문할 정점은 큐에 있는 정점 중 가중치가 가장 낮은 정점입니다.

만약 이미 방문하여 연결된 간선 모두를 큐에 넣었던 정점이면 continue를 해주고 방문하지 않은 정점에 연결된 간선만 모두 추가합니다.

 

두 방식 모두 N - 1개의 간선을 골랐으면 break를 하고 지금까지 더했던 가중치를 출력해줍니다.

 

 

[Kruskal]

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
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
 
typedef struct Point {
    int u;
    int v;
    int w;
};
 
vector<Point> list;
int parent[10001];
int N, M, ans, cnt;
 
bool cmp(Point a, Point b) {
    if (a.w < b.w) return true;
    else return false;
}
 
void init() {
    for (int i = 1; i <= N; i++) {
        parent[i] = i;
    }
}
 
int find(int v) {
    if (parent[v] == v) return v;
    return parent[v] = find(parent[v]);
}
 
void Union(int x, int y, int w) {
    int a = find(x);
    int b = find(y);
 
    if (a == b) return;
    parent[b] = a;
    ans += w;
    cnt++;
}
 
void func() {
    for (int i = 0; i < M; i++) {
        int u = list[i].u;
        int v = list[i].v;
        int w = list[i].w;
 
        Union(u, v, w);
        if (cnt == N - 1break;
    }
 
    cout << ans << '\n';
}
 
void input() {
    int u, v, w;
    cin >> N >> M;
    for (int i = 0; i < M; i++) {
        cin >> u >> v >> w;
        list.push_back({ u,v,w });
    }
    sort(list.begin(), list.end(), cmp);
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    input();
    init();
    func();
 
    return 0;
}
cs

 

 

[Prim]

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
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
 
vector<pair<intint> > list[10001];
bool visit[10001];
int N, M, ans, cnt;
 
void func() {
    priority_queue<pair<intint> > q;
    for (int i = 0; i < list[1].size(); i++) {
        q.push({ -list[1][i].second, list[1][i].first });
    }
    visit[1= true;
    
    while (!q.empty()) {
        int x = q.top().second;
        int w = -q.top().first;
        q.pop();
 
        if (visit[x]) continue;
        visit[x] = true;
        ans += w;
        cnt++;
        if (cnt == N - 1break;
 
        for (int i = 0; i < list[x].size(); i++) {
            int next = list[x][i].first;
            int nextw = list[x][i].second;
 
            q.push({ -nextw, next });
        }
    }
 
    cout << ans << '\n';
}
 
void input() {
    int u, v, w;
    cin >> N >> M;
    while(M--) {
        cin >> u >> v >> w;
        list[u].push_back({ v, w });
        list[v].push_back({ u, w });
    }
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    input();
    func();
 
    return 0;
}
cs

'algorithm > MST' 카테고리의 다른 글

boj 1647 도시 분할 계획  (0) 2021.03.19
boj 1922 네트워크 연결  (0) 2021.03.19

www.acmicpc.net/problem/10775

 

10775번: 공항

예제 1 : [2][?][?][1] 형태로 도킹시킬 수 있다. 3번째 비행기는 도킹시킬 수 없다. 예제 2 : [1][2][3][?] 형태로 도킹 시킬 수 있고, 4번째 비행기는 절대 도킹 시킬 수 없어서 이후 추가적인 도킹은 불

www.acmicpc.net

도킹하려는 게이트 번호인 x가 주어지면

union-find의 find를 이용하여 1 ~ x의 게이트 중 사용 가능한 게이트의 가장 큰 번호를 찾습니다.

찾은 번호인 p가 1 ~ x에 있으면 비행기를 도킹시켜주면 되고, parent[p] = p - 1로 바꿔줍니다.

p가 0이면 1 ~ x의 게이트 모두 사용이 불가능하므로 break를 하고 갯수를 출력해줍니다.

 

 

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
#include <iostream>
using namespace std;
 
int parent[100001], list[100001];
int N, M, ans;
 
int find(int v) {
    if (parent[v] == v) return v;
    return parent[v] = find(parent[v]);
}
 
void func() {
    for (int i = 0; i < M; i++) {
        int x = list[i];
        int p = find(x);
 
        if (!p) break;
        parent[p] = p - 1;
        ans++;
    }
 
    cout << ans << '\n';
}
 
void init() {
    for (int i = 1; i <= N; i++) {
        parent[i] = i;
    }
}
 
void input() {
    cin >> N >> M;
    for (int i = 0; i < M; i++) {
        cin >> list[i];
    }
    init();
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    input();
    func();
 
    return 0;
}
cs

'algorithm > Union-Find' 카테고리의 다른 글

boj 20040 사이클 게임  (0) 2021.06.27
boj 1043 거짓말  (0) 2021.04.05
boj 4195 친구 네트워크  (0) 2021.03.17
boj 1976 여행 가자  (0) 2021.03.17
boj 1717 집합의 표현  (0) 2021.02.06

www.acmicpc.net/problem/4195

 

4195번: 친구 네트워크

첫째 줄에 테스트 케이스의 개수가 주어진다. 각 테스트 케이스의 첫째 줄에는 친구 관계의 수 F가 주어지며, 이 값은 100,000을 넘지 않는다. 다음 F개의 줄에는 친구 관계가 생긴 순서대로 주어진

www.acmicpc.net

map을 이용하여 입력으로 이름이 들어오는 순서대로 인덱스를 부여합니다.

만약 이미 인덱스가 부여된 이름이라면 map에 저장된 인덱스를 가져옵니다.

 

이제 두 친구의 인덱스가 생겼으니 union-find로 둘을 이어줍니다.

이 때 Union 함수에서 a와 b가 다를때만 친구 네트워크 수를 b만큼 a에 더해줍니다.

 

 

 

[C++]

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
#include <iostream>
#include <string>
#include <map>
using namespace std;
 
map<stringint> m;
int parent[200001];
int friends[200001];
int N, idx;
 
int find(int v) {
    if (parent[v] == v) return v;
    return parent[v] = find(parent[v]);
}
 
void Union(int x, int y) {
    int a = find(x);
    int b = find(y);
 
    if (a != b) {
        parent[b] = a;
        friends[a] += friends[b];
    }
}
 
void input() {
    string str1, str2;
    int u, v;
    cin >> N;
    for (int i = 0; i < N; i++) {
        cin >> str1 >> str2;
 
        if (m.find(str1) == m.end()) {
            m.insert({ str1, idx });
            parent[idx] = idx;
            friends[idx] = 1;
            u = idx++;
        }
        else {
            u = m[str1];
        }
 
        if (m.find(str2) == m.end()) {
            m.insert({ str2, idx });
            parent[idx] = idx;
            friends[idx] = 1;
            v = idx++;
        }
        else {
            v = m[str2];
        }
 
        Union(u, v);
 
        cout << friends[find(u)] << '\n';
    }
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    int tc;
    cin >> tc;
    while (tc--) {
        input();
        m.clear();
        idx = 0;
    }
 
    return 0;
}
cs

 

 

[Java]

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
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;
 
public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static StringBuffer sb = new StringBuffer();
    static Map<String, Integer> m = new HashMap<>();
    static int parent[][] = new int[200001][2];
    static int N, idx = 1;
 
    static int find(int v) {
        if (parent[v][0== v)
            return parent[v][0];
        return parent[v][0= find(parent[v][0]);
 
    }
 
    static void union(int u, int v) {
        int a = find(u);
        int b = find(v);
 
        if (a != b) {
            parent[a][1+= parent[b][1];
            parent[b][0= parent[a][0];
        }
        sb.append(parent[a][1]).append("\n");
    }
 
    static void init() {
        for (int i = 1; i <= N * 2; i++) {
            parent[i][0= i;
            parent[i][1= 1;
        }
    }
 
    static void input() throws Exception {
        String str1, str2;
        int u, v;
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        init();
        for (int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine());
            str1 = st.nextToken();
            str2 = st.nextToken();
 
            if (m.containsKey(str1))
                u = m.get(str1);
            else {
                m.put(str1, idx);
                u = idx++;
            }
 
            if (m.containsKey(str2))
                v = m.get(str2);
            else {
                m.put(str2, idx);
                v = idx++;
            }
 
            if (v < u) {
                int tmp = u;
                u = v;
                v = tmp;
            }
 
            union(u, v);
        }
    }
 
    public static void main(String[] args) throws Exception {
        st = new StringTokenizer(br.readLine());
        int tc = Integer.parseInt(st.nextToken());
        while (tc-- > 0) {
            input();
            m.clear();
            idx = 1;
        }
        System.out.println(sb.toString());
    }
}
cs

'algorithm > Union-Find' 카테고리의 다른 글

boj 20040 사이클 게임  (0) 2021.06.27
boj 1043 거짓말  (0) 2021.04.05
boj 10775 공항  (0) 2021.03.17
boj 1976 여행 가자  (0) 2021.03.17
boj 1717 집합의 표현  (0) 2021.02.06

www.acmicpc.net/problem/1976

 

1976번: 여행 가자

동혁이는 친구들과 함께 여행을 가려고 한다. 한국에는 도시가 N개 있고 임의의 두 도시 사이에 길이 있을 수도, 없을 수도 있다. 동혁이의 여행 일정이 주어졌을 때, 이 여행 경로가 가능한 것인

www.acmicpc.net

두 가지 방법으로 해결하였습니다. 하나는 union-find를 이용한 방법, 하나는 dfs를 이용한 방법입니다.

 

먼저 union-find 방법입니다.

입력에서 인접한 도시의 정보가 주어집니다.

(i, j)가 0이면 인접X, 1이면 인접한 도시입니다.

1이 주어질때마다 union-find로 parent를 갱신해줍니다.

 

마지막으로 M개 도시의 parent가 모두 같으면 YES, 하나라도 다르면 NO입니다.

 

 

[Union-find]

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
#include <iostream>
#include <vector>
using namespace std;
 
vector<int> travel;
int parent[201];
int N, M;
 
void init() {
    for (int i = 1; i <= N; i++) {
        parent[i] = i;
    }
}
 
int find(int v) {
    if (parent[v] == v) return v;
    return parent[v] = find(parent[v]);
}
 
void func() {
    int x = find(travel[0]);
    for (int i = 1; i < M; i++) {
        int y = find(travel[i]);
 
        if (x != y) {
            cout << "NO\n";
            return;
        }
    }
 
    cout << "YES\n";
}
 
void Union(int x, int y) {
    if (x > y) swap(x, y);
    
    int a = find(x);
    int b = find(y);
 
    parent[b] = a;
}
 
void input() {
    int k;
    cin >> N >> M;
    init();
    for (int i = 1; i <= N; i++) {
        for (int j = 1; j <= N; j++) {
            cin >> k;
            if (k) {                
                Union(i, j);
            }
        }
    }
    
    for (int i = 0; i < M; i++) {
        cin >> k;
        travel.push_back(k);
    }
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    input();
    func();
 
    return 0;
}
cs

 

그 다음은 dfs를 이용한 방법입니다.

위와 마찬가지로 0이면 인접X, 1이면 인접한 정점이므로 벡터에 넣어줍니다.

그 다음 M개의 도시 중 첫번째 도시를 루트로 dfs를 돌려줍니다. (이 때 방문체크를 한 것을 이용합니다.)

 

마지막으로 dfs로 순회하면서 M개의 도시를 모두 방문하였는지 체크해줍니다.

하나라도 방문을 하지 않았으면 연결이 안되어있다는 말이므로 NO를 출력해줍니다.

M개의 도시를 모두 방문하였으면 YES를 출력합니다.

 

 

[dfs]

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
#include <iostream>
#include <vector>
using namespace std;
 
vector<int> graph[201], travel;
bool visit[201];
int N, M;
 
void func() {
    for (int i = 0; i < M; i++) {
        int x = travel[i];
        if (visit[x]) continue;
 
        cout << "NO\n";
        return;
    }
 
    cout << "YES\n";
}
 
void dfs(int v) {
    visit[v] = true;
 
    for (int i = 0; i < graph[v].size(); i++) {
        int next = graph[v][i];
 
        if (visit[next]) continue;
        dfs(next);
    }
}
 
void input() {
    int k;
    cin >> N >> M;
    for (int i = 1; i <= N; i++) {
        for (int j = 1; j <= N; j++) {
            cin >> k;
            if (k) graph[i].push_back(j);
        }
    }
 
    for (int i = 0; i < M; i++) {
        cin >> k;
        travel.push_back(k);
    }
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    input();
    dfs(travel[0]);
    func();
 
    return 0;
}
cs

'algorithm > Union-Find' 카테고리의 다른 글

boj 20040 사이클 게임  (0) 2021.06.27
boj 1043 거짓말  (0) 2021.04.05
boj 10775 공항  (0) 2021.03.17
boj 4195 친구 네트워크  (0) 2021.03.17
boj 1717 집합의 표현  (0) 2021.02.06

www.acmicpc.net/problem/14889

 

14889번: 스타트와 링크

예제 2의 경우에 (1, 3, 6), (2, 4, 5)로 팀을 나누면 되고, 예제 3의 경우에는 (1, 2, 4, 5), (3, 6, 7, 8)로 팀을 나누면 된다.

www.acmicpc.net

조합으로 N/2개를 뽑은 후에 뽑은 것들의 조합의 능력치를 N^2으로 각각 계산해줍니다.

그 다음 abs(a-b)의 차이의 최소를 구해 출력해주시면 됩니다.

 

 

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
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
 
public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static boolean pick[] = new boolean[21];
    static int list[][] = new int[21][21];
    static int N, ans = Integer.MAX_VALUE;
 
    static void func(int idx, int cnt) {
        if (cnt == N / 2) {
            int a = 0;
            int b = 0;
            for (int i = 0; i < N; i++) {
                for (int j = i + 1; j < N; j++) {
                    if (pick[i] == pick[j]) {
                        if (pick[i])
                            a += (list[i][j] + list[j][i]);
                        else
                            b += (list[i][j] + list[j][i]);
                    }
                }
            }
 
            ans = Math.min(ans, Math.abs(a - b));
            return;
        }
 
        for (int i = idx; i < N; i++) {
            pick[i] = true;
            func(i + 1, cnt + 1);
            pick[i] = false;
        }
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        for (int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine());
            for (int j = 0; j < N; j++) {
                list[i][j] = Integer.parseInt(st.nextToken());
            }
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func(00);
        System.out.println(ans);
    }
}
cs

'algorithm > dfs' 카테고리의 다른 글

boj 2239 스도쿠  (0) 2021.04.16
boj 2458 키 순서  (0) 2021.04.13
boj 2023 신기한 소수  (0) 2021.03.16
boj 14500 테트로미노  (0) 2021.03.15
boj 16922 로마 숫자 만들기  (0) 2021.02.24

www.acmicpc.net/problem/2589

 

2589번: 보물섬

보물섬 지도를 발견한 후크 선장은 보물을 찾아나섰다. 보물섬 지도는 아래 그림과 같이 직사각형 모양이며 여러 칸으로 나뉘어져 있다. 각 칸은 육지(L)나 바다(W)로 표시되어 있다. 이 지도에서

www.acmicpc.net

칸이 육지인 곳에서 bfs를 돌려서 거리가 가장 긴 시간을 출력하는 문제입니다.

이 문제는 육지인 모든 칸을 시작점으로 잡고 bfs를 돌려주면 되겠습니다.

한 번의 bfs가 끝나면 visit배열을 초기화 해주어야합니다.

 

 

[C++]

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
#include <iostream>
#include <queue>
#include <cstring>
#include <algorithm>
using namespace std;
 
typedef struct Point {
    int x;
    int y;
    int cnt;
}Point;
 
char list[60][60];
bool visit[60][60];
int direct[4][2= { {0,1},{1,0},{0,-1},{-1,0} };
int N, M, ans;
 
void bfs(int sx, int sy) {
    queue<Point> q;
    q.push({ sx,sy,0 });
    visit[sx][sy] = true;
    while (!q.empty()) {
        int x = q.front().x;
        int y = q.front().y;
        int cnt = q.front().cnt;
        q.pop();
 
        ans = max(ans, cnt);
        for (int i = 0; i < 4; i++) {
            int nx = x + direct[i][0];
            int ny = y + direct[i][1];
 
            if (nx < 0 || ny < 0 || nx >= N || ny >= M) continue;
            if (visit[nx][ny] || list[nx][ny] == 'W'continue;
 
            q.push({ nx,ny,cnt + 1 });
            visit[nx][ny] = true;
        }
    }
}
 
void func() {
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            if (list[i][j] == 'W'continue;
 
            bfs(i, j);
            memset(visit, falsesizeof(visit));
        }
    }
 
    cout << ans << '\n';
}
 
void input() {
    cin >> N >> M;
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            cin >> list[i][j];
        }
    }
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    input();
    func();
 
    return 0;
}
cs

 

 

[Java]

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
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Deque;
import java.util.StringTokenizer;
 
public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static char list[][] = new char[60][60];
    static boolean visit[][] = new boolean[60][60];
    static int direct[][] = { { 01 }, { 10 }, { 0-1 }, { -10 } };
    static int N, M, ans;
 
    static void bfs(int sx, int sy) {
        Deque<int[]> dq = new ArrayDeque<>();
        dq.add(new int[] { sx, sy, 0 });
        visit[sx][sy] = true;
        while (!dq.isEmpty()) {
            int x = dq.peek()[0];
            int y = dq.peek()[1];
            int cnt = dq.poll()[2];
 
            ans = Math.max(ans, cnt);
            for (int i = 0; i < 4; i++) {
                int nx = x + direct[i][0];
                int ny = y + direct[i][1];
 
                if (nx < 0 || ny < 0 || nx >= N || ny >= M)
                    continue;
                if (visit[nx][ny] || list[nx][ny] == 'W')
                    continue;
 
                dq.add(new int[] { nx, ny, cnt + 1 });
                visit[nx][ny] = true;
            }
        }
    }
 
    static void func() {
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < M; j++) {
                if (list[i][j] == 'W')
                    continue;
 
                bfs(i, j);
                for (int k = 0; k < N; k++)
                    Arrays.fill(visit[k], false);
            }
        }
        
        System.out.println(ans);
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
 
        for (int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine());
            list[i] = st.nextToken().toCharArray();
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func();
    }
}
cs

 

'algorithm > bfs' 카테고리의 다른 글

boj 9205 맥주 마시면서 걸어가기  (0) 2021.03.25
boj 1600 말이 되고픈 원숭이  (0) 2021.03.24
boj 11559 Puyo Puyo  (0) 2021.02.26
boj 15653 구슬 탈출 4  (0) 2021.02.22
boj 1525 퍼즐  (0) 2021.02.19

www.acmicpc.net/problem/2023

 

2023번: 신기한 소수

수빈이가 세상에서 가장 좋아하는 것은 소수이고, 취미는 소수를 가지고 노는 것이다. 요즘 수빈이가 가장 관심있어 하는 소수는 7331이다. 7331은 소수인데, 신기하게도 733도 소수이고, 73도 소수

www.acmicpc.net

메모리 제한이 4MB이라서 에라토스테네스의 체를 사용할 수 없습니다.

그래서 소수인지 판별하는 부분을 2부터 반복문을 돌리는 방법을 선택해서 시간초과가 뜰것 같았지만 다행히도 AC를 받았습니다.

 

우선 문제의 7331을 보면 7331도 소수, 733도 소수, 73도 소수, 7도 소수입니다.

즉 일의자리부터 숫자 하나씩 뺀 부분 숫자도 소수여야합니다.

 

저는 백트래킹으로 맨 앞의 자리부터 구하였습니다.

우선 맨 앞의 자리에 올 수 있는 숫자는 2, 3, 5, 7입니다. (일의자리 소수)

각 숫자가 맨 앞의 올 경우를 구하기 위해 4번의 dfs를 돌립니다.

 

dfs에서는 일의자리로 올 숫자를 구하는것이기 때문에 짝수가 올 수 없으므로 홀수만 돌려줍니다.

next가 소수이면 재귀를 돌려주었고, 뽑은 숫자가 N개가 되면 지금까지 뽑은 숫자를 출력합니다.

 

 

[C++]

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
#include <iostream>
using namespace std;
 
int N;
 
bool prime(int x) {
    for (int i = 2; i*<= x; i++) {
        if (!(x % i)) return false;
    }
 
    return true;
}
 
void dfs(int cnt, int x) {
    if (cnt == N) {
        cout << x << '\n';
        return;
    }
 
    for (int i = 1; i <= 9; i += 2) {
        int next = x * 10 + i;
        if (!prime(next)) continue;
        dfs(cnt + 1, next);
    }
}
 
void func() {
    dfs(12);
    dfs(13);
    dfs(15);
    dfs(17);
}
 
void input() {
    cin >> N;
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    input();
    func();
 
    return 0;
}
cs

 

 

[Java]

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
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
 
public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static StringBuffer sb = new StringBuffer();
    static int N;
 
    static boolean primeCheck(int x) {
        for (int i = 2; i * i <= x; i++) {
            if (x % i == 0)
                return false;
        }
 
        return true;
    }
 
    static void dfs(int cnt, int x) {
        if (cnt == N) {
            sb.append(x).append("\n");
            return;
        }
 
        for (int i = 1; i <= 9; i += 2) {
            int next = x * 10 + i;
            if (!primeCheck(next))
                continue;
 
            dfs(cnt + 1, next);
        }
    }
 
    static void func() {
        dfs(12);
        dfs(13);
        dfs(15);
        dfs(17);
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func();
        System.out.print(sb.toString());
    }
}
cs

'algorithm > dfs' 카테고리의 다른 글

boj 2458 키 순서  (0) 2021.04.13
boj 14889 스타트와 링크  (0) 2021.03.17
boj 14500 테트로미노  (0) 2021.03.15
boj 16922 로마 숫자 만들기  (0) 2021.02.24
boj 1987 알파벳  (0) 2021.02.18

www.acmicpc.net/problem/16719

 

16719번: ZOAC

2018년 12월, 처음 시작하게 된 ZOAC의 오프닝을 맡은 성우는 누구보다 화려하게 ZOAC를 알리려 한다. 앞 글자부터 하나씩 보여주는 방식은 너무 식상하다고 생각한 성우는 문자열을 보여주는 새로

www.acmicpc.net

문자열의 길이를 1부터 1씩 늘려가며 아직 보여주지 않은 문자 중 추가했을 때 문자열이 사전 순으로 가장 앞에 오는 문자열을 출력합니다.

 

저는 길이에 변화를 시켜가며 모든 경우를 다 확인하였습니다.

반복문을 통해 아직 추가하지 않은 문자를 포함한 문자열을 모두 벡터에 넣습니다. 이 때 추가한 문자열의 방문체크를 위해 인덱스를 추가합니다.

그 중 사전 순으로 가장 앞에 오는 문자열을 출력하고, 그 문자열에서 추가한 문자의 인덱스를 가져와 방문체크를 합니다.

 

문자열의 길이가 1 ~ size 가 될때까지 반복합니다.

 

 

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
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
using namespace std;
 
vector<pair<stringint> > v;
bool visit[110];
string str;
 
void func() {
    int ssize = str.size();
    for (int i = 0; i < ssize; i++) {
        for (int j = 0; j < ssize; j++) {
            if (visit[j]) continue;
 
            string tmp = "";
            for (int k = 0; k < ssize; k++) {
                if (visit[k] || j == k) {
                    tmp += str[k];
                }
            }
 
            v.push_back({ tmp, j });
        }
        sort(v.begin(), v.end());
        cout << v[0].first << '\n';
        visit[v[0].second] = true;
        v.clear();
    }
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    cin >> str;
    func();
 
    return 0;
}
cs

'algorithm > Implementation' 카테고리의 다른 글

boj 17144 미세먼지 안녕!  (0) 2021.04.14
boj 2564 경비원  (0) 2021.04.13
boj 3085 사탕 게임  (0) 2021.02.26
boj 8320 직사각형을 만드는 방법  (0) 2021.02.25
boj 3985 롤 케이크  (0) 2021.02.25

www.acmicpc.net/problem/14500

 

14500번: 테트로미노

폴리오미노란 크기가 1×1인 정사각형을 여러 개 이어서 붙인 도형이며, 다음과 같은 조건을 만족해야 한다. 정사각형은 서로 겹치면 안 된다. 도형은 모두 연결되어 있어야 한다. 정사각형의 변

www.acmicpc.net

크기가 N * M인 종이에 위와 같은 테트로미노를 하나 놓습니다.

그리고 이 테트로미노는 회전, 대칭한 모양이 가능합니다.

 

한개를 놓으면 되기때문에 각 칸에서의 모든 경우를 다 체크해야합니다.

테트로미노 중 'ㅏ', 'ㅓ', 'ㅗ', 'ㅜ' 모양을 제외하면 한붓 그리기가 가능하므로 dfs로 구할 수 있습니다.

dfs로 가능한 모양들은 dfs를 돌려줘서 4칸을 방문할 때마다 ans를 갱신해줍니다.

 

 

 

그 다음 한붓그리기가 안되는 모양인 'ㅏ', 'ㅓ', 'ㅗ', 'ㅜ' 모양에 대한 처리를 합니다.

저는 이 모양들을 좌표로 이용하였습니다.

 

 

위와 같은 그림처럼 좌표값을 하나하나 비교하였고 각 모양마다 올 수 있는 최소, 최대 좌표값의 범위를 체크하고, 

각각 합의 최댓값을 갱신해주었습니다.

 

 

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
#include <iostream>
#include <algorithm>
using namespace std;
 
int list[501][501];
bool visit[501][501];
int direct[4][2= { {0,1},{1,0},{0,-1},{-1,0} };
int N, M, ans;
 
void dfs(int x, int y, int cnt, int sum) {
    if (cnt == 4) {
        ans = max(ans, sum);
        return;
    }
 
    for (int i = 0; i < 4; i++) {
        int nx = x + direct[i][0];
        int ny = y + direct[i][1];
 
        if (nx < 0 || ny < 0 || nx >= N || ny >= M) continue;
        if (visit[nx][ny]) continue;
 
        visit[nx][ny] = true;
        dfs(nx, ny, cnt + 1, sum + list[nx][ny]);
        visit[nx][ny] = false;
    }
}
 
void func() {
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            visit[i][j] = true;
            dfs(i, j, 1, list[i][j]);
            visit[i][j] = false;
 
            if (i + 2 < N && j + 1 < M) {
                ans = max(ans, list[i][j] + list[i + 1][j] + list[i + 2][j] + list[i + 1][j + 1]);
            }
            if (i + 1 < N && j - 1 >= 0 && j + 1 < M) {
                ans = max(ans, list[i][j] + list[i + 1][j - 1+ list[i + 1][j] + list[i + 1][j + 1]);
            }
            if (i + 1 < N && j + 2 < M) {
                ans = max(ans, list[i][j] + list[i][j + 1+ list[i][j + 2+ list[i + 1][j + 1]);
            }
            if (i - 1 >= 0 && i + 1 < N && j + 1 < M) {
                ans = max(ans, list[i][j] + list[i - 1][j + 1+ list[i][j + 1+ list[i + 1][j + 1]);
            }
        }
    }
 
    cout << ans << '\n';
}
 
void input() {
    cin >> N >> M;
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            cin >> list[i][j];
        }
    }
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    input();
    func();
 
    return 0;
}
cs

'algorithm > dfs' 카테고리의 다른 글

boj 14889 스타트와 링크  (0) 2021.03.17
boj 2023 신기한 소수  (0) 2021.03.16
boj 16922 로마 숫자 만들기  (0) 2021.02.24
boj 1987 알파벳  (0) 2021.02.18
boj 3109 빵집  (0) 2021.02.18

www.acmicpc.net/problem/14719

 

14719번: 빗물

첫 번째 줄에는 2차원 세계의 세로 길이 H과 2차원 세계의 가로 길이 W가 주어진다. (1 ≤ H, W ≤ 500) 두 번째 줄에는 블록이 쌓인 높이를 의미하는 0이상 H이하의 정수가 2차원 세계의 맨 왼쪽 위치

www.acmicpc.net

저는 2가지 방법으로 해결하였습니다.

 

하나는 그냥 구현으로, 다른 하나는 세그먼트 트리를 이용하였습니다.

 

먼저 블록의 최대 높이를 가진 인덱스(idx)를 구합니다.

그리고 왼쪽에서 idx까지, 오른쪽에서 idx까지 순회하면서 현재 최대 높이를 갱신해주고,

만약 현재 최대높이보다 블록의 높이가 더 작으면 그 차이만큼 더해주는 방식입니다.

 

 

emoney96.tistory.com/154

 

boj 2304 창고 다각형

www.acmicpc.net/problem/2304 2304번: 창고 다각형 첫 줄에는 기둥의 개수를 나타내는 정수 N이 주어진다. N은 1 이상 1,000 이하이다. 그 다음 N 개의 줄에는 각 줄에 각 기둥의 왼쪽 면의 위치를 나타내는

emoney96.tistory.com

세그먼트 트리는 위의 문제와 같은 방식입니다.

 

트리에 각 높이의 최댓값을 저장합니다.

 

그 다음 1 ~ N번 블록을 순회하면서 자신을 포함한 왼쪽, 오른쪽 중 최고 높이를 구합니다.

왼쪽 오른쪽 최고 높이 중 낮은 높이만큼 빗물이 쌓이므로 블록높이를 뺀 값을 더해줍니다.

 

 

[구현]

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
#include <iostream>
#include <algorithm>
using namespace std;
 
int list[501];
int N, M, maxheight, idx;
 
void func() {
    int ans = 0;
    int nowmax = 0;
    for (int i = 1; i <= idx; i++) {
        nowmax = max(nowmax, list[i]);
 
        if (nowmax > list[i]) {
            ans += (nowmax - list[i]);
        }
    }
 
    nowmax = 0;
    for (int i = N; i > idx; i--) {
        nowmax = max(nowmax, list[i]);
 
        if (nowmax > list[i]) {
            ans += (nowmax - list[i]);
        }
    }
 
    cout << ans << '\n';
}
 
void input() {
    cin >> M >> N;
    for (int i = 1; i <= N; i++) {
        cin >> list[i];
        if (maxheight < list[i]) {
            maxheight = list[i];
            idx = i;
        }
    }
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    input();
    func();
 
    return 0;
}
cs

 

 

[세그먼트 트리]

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
#include <iostream>
#include <algorithm>
using namespace std;
 
int list[501], tree[2001];
int N, M;
 
int init(int node, int s, int e) {
    if (s == e) {
        return tree[node] = list[s];
    }
 
    int m = (s + e) / 2;
    return tree[node] = max(init(node * 2, s, m), init(node * 2 + 1, m + 1, e));
}
 
int query(int node, int s, int e, int l, int r) {
    if (l > e || s > r) return 0;
    if (l <= s && e <= r) return tree[node];
 
    int m = (s + e) / 2;
    return max(query(node * 2, s, m, l, r), query(node * 2 + 1, m + 1, e, l, r));
}
 
void func() {
    int ans = 0;
    for (int i = 1; i <= N; i++) {
        int l = query(11, N, 1, i);
        int r = query(11, N, i + 1, N);
 
        int result = min(l, r);
 
        if (list[i] < result) {
            ans += result - list[i];
        }
    }
 
    cout << ans << '\n';
}
 
void input() {
    cin >> M >> N;
    for (int i = 1; i <= N; i++) {
        cin >> list[i];
    }
    init(11, N);
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    input();
    func();
 
    return 0;
}
cs

'algorithm > SegmentTree' 카테고리의 다른 글

boj 12846 무서운 아르바이트  (0) 2022.08.19
boj 1849 순열  (0) 2021.09.08
boj 2304 창고 다각형  (0) 2021.02.25
boj 14438 수열과 쿼리 17  (0) 2021.02.21
boj 13537 수열과 쿼리 1  (0) 2021.02.21

+ Recent posts