알고리즘/BAEKJOON

백준 6118번 숨바꼭질

pureworld 2019. 5. 11. 14:34

백준 6118번 숨바꼭질

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
#include <iostream>
#include<vector>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
 
int n, m;
int djikstra[20002];  //djisktra[i]는 1부터 i까지 가는 경로의 길이를 저장하는 배열
vector<int> arr[20002];  //edge 간선을 의미
void route(int nowlocate) {
    queue<int> q;
    q.push(nowlocate);
    while (!q.empty()) {
        int locate = q.front();
        q.pop();    
        for (int i = 0; i < arr[locate].size(); i++) {
            if (!djikstra[arr[locate][i]]) {        //길이 이어지지 않았으면 이어줌
                djikstra[arr[locate][i]] = djikstra[locate] + 1;
                q.push(arr[locate][i]);
            }
        }
    }
}
int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cin >> n >> m;
    for (int i = 0; i < m; i++) {
        int a, b;
        cin >> a >> b;
        arr[a].push_back(b);
        arr[b].push_back(a);
    }
    route(1);
    int Max = 0;
    for (int i = 2; i <= n; i++) {
        if (djikstra[i] > Max)
            Max = djikstra[i];
    }
    int cnt = 0, locate = 98764321;
    for (int i = 2; i <= n; i++) {
        if (djikstra[i] == Max) {
            if (locate > i)
                locate = i;
            cnt++;
        }
    }
    cout << locate << " " << Max << " " << cnt;
    return 0;
}
 
cs

출처:https://www.acmicpc.net/problem/6118

메모리 초과,시간초과로 계속 문제를 못맞추고 있었는데 생각보다 간단하게 해결할 수 있는 문제였습니다. 



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
#include <iostream>
#include<vector>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
 
int n, m;
int djikstra[20002];
vector<int> arr[20002];
bool visited[20002];
void route(int nowlocate) {
    queue<pair<intint> > q;
    q.push(make_pair( nowlocate,0 ));
    int ret = 987654321;
    while (!q.empty()) {
        int locate = q.front().first;
        int cnt = q.front().second;
        q.pop();
        visited[locate] = 1;
                
        for (int i = 0; i < arr[locate].size(); i++) {
            if (!visited[arr[locate][i]]) {
                if (djikstra[arr[locate][i]] == 0 || djikstra[arr[locate][i]] >= cnt+1) {
                    djikstra[arr[locate][i]] = cnt+1;
                    q.push(make_pair(arr[locate][i], cnt + 1));
                }
            }
        }
    }
}
int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cin >> n >> m;
    for (int i = 0; i < m; i++) {
        int a, b;
        cin >> a >> b;
        if (a == 1) {
            djikstra[b] = 1;
        }
        if (b == 1) {
            djikstra[a] = 1;
        }
        arr[a].push_back(b);
        arr[b].push_back(a);
    }
    route(1);
    int Max = 0;
    for (int i = 2; i <= n; i++) {
        if (djikstra[i] > Max)
            Max = djikstra[i];
    }
    int cnt = 0, locate = 98764321;
    for (int i = 2; i <= n; i++) {
        if (djikstra[i] == Max) {
            if (locate > i)
                locate = i;
            cnt++;
        }
    }
    cout << locate << " " << Max << " " << cnt;
 
 
    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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include <iostream>
#include<vector>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
 
int n, m;
int djikstra[20001];
vector<int> arr[20001];
bool visited[20001];
int route(int nowlocate, int dest) {
    queue<pair<intint> > q;
    q.push(make_pair( nowlocate,0 ));
    int ret = 987654321;
    while (!q.empty()) {
        int locate = q.front().first;
        int cnt = q.front().second;
        visited[locate] = 1;
        q.pop();
        if (locate == dest) ret = min(ret, cnt);
        for (int i = 0; i < arr[locate].size(); i++) {
            if(!visited[arr[locate][i]])
                q.push(make_pair(arr[locate][i], cnt + 1));
        }
    }
    return ret;
}
 
 
int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cin >> n >> m;
    for (int i = 0; i < m; i++) {
        int a, b;
        cin >> a >> b;
        if (a == 1) {
            djikstra[b] = 1;
        }
        if (b == 1) {
            djikstra[a] = 1;
        }
        arr[a].push_back(b);
        arr[b].push_back(a);
    }
 
    for (int k = 2; k <= n; k++) {
        memset(visited, 0sizeof(visited));
        if (djikstra[k] == 0) {
            djikstra[k] = route(1, k);
        }
    }
 
    int Max = 0;
    for (int i = 2; i <= n; i++) {
        if (djikstra[i] > Max)
            Max = djikstra[i];
    }
    int cnt = 0, locate = 98764321;
    for (int i = 2; i <= n; i++) {
        if (djikstra[i] == Max ) {
            if (locate > i)
                locate = i;
            cnt++;
        }
    }
    cout << locate << " " << Max << " " << cnt;
 
    return 0;
}
cs

아무생각없이 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
#include <iostream>
#include<vector>
#include<algorithm>
#include<cstring>
using namespace std;
 
int n, m;
int arr[20001][20001];
int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cin >> n >> m;
    
    for (int i = 0; i < m; i++) {
        int a, b;
        cin >> a >> b;
        arr[b][a]=arr[a][b] = 1;
    }
    for (int i = 2; i <= n; i++) {
        for (int j = 2; j <= n; j++) {
            if (i == j)continue// 제자리 이동 제외
            if (arr[j][i] == 0continue;// 길이 없는 경우 제외
            if (arr[1][i] == 0 || arr[1][i] > arr[1][j] + arr[j][i]) {
                arr[1][i] = arr[1][j] + arr[j][i];
            }
        }
    }
    int Max = 0;
    for (int i = 2; i <= n; i++) {
        if (arr[1][i] > Max)
            Max = arr[1][i];
    }
    int cnt = 0;
    int locate = 98764321;
    for (int i = 2; i <= n; i++) {
        if (arr[1][i] == Max) {
            if (locate > i)
                locate = i;
            cnt++;
        }
    }
    cout << locate << " " << Max << " "<<cnt;
 
    return 0;
}
cs

간선을 2차원배열로 기록해서 메모리초과가 나는 코드 였습니다.

2만*2만=4억, 메모리 제한 256MB는 대략 6천만까지 버티니까 메모리제한에서 터지네요