문제 출처 : BOJ 1199 - 오일러 회로 https://www.acmicpc.net/problem/1199
1199번: 오일러 회로
첫 줄에는 정점의 수 N(1 ≤ N ≤ 1,000)이 주어진다. 그리고 다음 N개의 줄에 대해 인접행렬의 정보가 주어진다. i+1번째 줄에는 i번 정점에 대한 인접행렬이 주어진다. 두 정점 사이에 간선이 여러
www.acmicpc.net
정점의 수와 인접행렬의 정보가 주어지면, 오일러 회로 경로를 출력하는 문제이다.
3시간동안 시간 초과의 늪에 빠져있다가 드디어 빠져나왔다.

아래에 있는 코드가 내가 처음 짠 코드이다.
시간 초과인데 큰 걸 고칠 생각은 안하고 찔끔찔끔 고치다가 위같은 결과물이 나왔다.
#include <iostream>
#include <vector>
using namespace std;
int n, cnt = 0, arr[1001][1001], lines[1001];
void dfs(int cur) {
for (int i = 1; i <= n; i++) {
while (arr[cur][i]) {
arr[cur][i]--;
arr[i][cur]--;
dfs(i);
}
}
cout << cur << ' ';
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL); cout.tie(NULL);
cin >> n;
for (int i = 1; i <= n; i++) {
int sum = 0;
for (int j = 1; j <= n; j++) {
cin >> arr[i][j];
sum += arr[i][j];
}
if (sum % 2) {
cout << "-1\n";
return 0;
}
cnt += sum;
}
cnt /= 2;
dfs(1);
cout << '\n';
return 0;
}
arr[][] 배열에 행렬 정보를 받고, 이를 그대로 dfs에 적용시켜 1부터 n까지 탐색하면서 간선의 정보를 찾았다.
도대체 무엇이 잘못된건지 생각해보다가 평소에 배열보다 더 자주쓰던 리스트, 즉 벡터를 써보기로 했다.
최종 코드
#include <iostream>
#include <vector>
using namespace std;
int n, cnt = 0;
int arr[1001][1001];
vector<int> v[1001];
vector<int> ans;
void dfs(int cur) {
while (!v[cur].empty()) {
if (arr[cur][v[cur].back()]) {
arr[cur][v[cur].back()]--;
arr[v[cur].back()][cur]--;
dfs(v[cur].back());
}
else v[cur].pop_back();
}
cout << cur + 1 << ' ';
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL); cout.tie(NULL);
cin >> n;
for (int i = 0; i < n; i++) {
int sum = 0;
for (int j = 0; j < n; j++) {
cin >> arr[i][j];
if (arr[i][j]) v[i].push_back(j);
sum += arr[i][j];
}
if (sum % 2) {
cout << "-1\n";
return 0;
}
}
dfs(0);
cout << '\n';
return 0;
}
위의 틀린 코드를 전부 갈아엎고 처음부터 다시 썼다.
arr[][] 배열에는 간선 개수에 대한 정보만 저장해두고,
dfs에서는 벡터 v에 저장된 정보를 이용해서 그래프를 탐색하는 방식이다.
dfs() 함수에서 v[cur]를 탐색할 때 back() 함수를 쓴 것은,
처음에 for (int i = 0; i < v[cur].size(); i++) 이런 식으로 짰다가
arr[cur][v[cur][i]] == 0일 때 v[cur][i]를 어떻게 쉽게 삭제할지 고민하다가 저렇게 되었다.
이렇게 간단하게 풀 수 있는 문제였는데 문제에서 인접 행렬로 주어지다보니까 눈이 돌아버린 것 같다.
오늘 2차 백신을 맞고 와서 몸이 너무 안좋았는데
정답률이 무려 12.828%인 문제를 풀어서 기분이 좋아졌다.
'BOJ' 카테고리의 다른 글
(C++) BOJ/백준 23327 - 리그전 오브 레전드 (0) | 2022.01.10 |
---|---|
(C++) 백준/BOJ 15658 - 연산자 끼워넣기 (2) (0) | 2021.09.28 |
(C++) BOJ/백준 10830 - 행렬 제곱 (0) | 2021.09.28 |
(C++) BOJ/백준 3584 - 가장 가까운 공통 조상 (0) | 2021.09.28 |
(C++) BOJ/백준 1780 - 종이의 개수 (0) | 2021.09.27 |