풀이
[문제 풀이]
이 문제는 잘 생각해보면 이미 이용한 경로를 통해서도 다시 방문을 할 수 있으므로, i번째에 N번째 노드를 방문한 경우를 이용해 i+1번째에 각 노드에 방문할 수 있는 경로가 몇 개인지 계산하면 되는 문제다.
이를 잘 생각해보면 이전에 작은 문제의 해결방법을 이용해 다음 문제를 풀 수 있으므로 DP 문제로 생각할 수 있다.
그림으로 보면 초록색 부분을 채워 나가면 된다.
N개의 노드가 존재하고 i번째에서 N번째 노드를 방문한 경우를 이용해 i+1번째 노드에는 몇 가지 경로가 존재하는지 빠르게 계산할 수 있다.
[아이디어 정리]
- N * 8 크기의 배열을 만든다.
- 현재 i번째 이동했을 때, N번째 노드를 방문하는 경우를 배열에 저장한다.
- 이를 이용해 i+1번째에 N번째 노드로 방문하는 경우의 수가 얼마인지 계산해 나간다.
- 최종적으로 7번째에 방문할 수 있는 모든 경우의 수를 더해 출력한다.
Code
#include <vector>
#include <iostream>
#include <algorithm>
#include <queue>
#include <string>
#include <cmath>
using namespace std;
const int mod = 1000000000 + 7;
int main()
{
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int N, M;
cin >> N >> M;
int a, b;
vector<vector<int>>v(N+1);
for (int i = 0; i < M; i++)
{
cin >> a >> b;
v[a].push_back(b);
v[b].push_back(a);
}
int ans = 0;
vector<vector<int>> m(N + 1, vector<int>(8, 0));
queue<int> q;
int nowCnt = 0, node;
for (int i = 1; i <= N; i++)
{
q.push(i);
m[i][0] = 1;
}
while (!q.empty()) {
if (nowCnt >= 7)
{
break;
}
while (!q.empty())
{
node = q.front();
q.pop();
for (int j = 0; j < v[node].size(); j++)
{
int nxtN = v[node][j];
m[nxtN][nowCnt + 1] += m[node][nowCnt];
m[nxtN][nowCnt + 1] %= mod;
}
}
nowCnt++;
for (int j=1; j<=N; j++)
{
if (m[j][nowCnt])
{
q.push(j);
}
}
}
for (int j=1; j<=N; j++)
{
ans += m[j][7];
ans %= mod;
}
cout << ans;
return 0;
}
새해 기념으로 문제의 내용에 새해가 들어간 문제를 풀었다.
이 문제는 처음에 DP라고 생각하지 않고 풀어서 코드가 많이 더러워 졌다;;
queue를 이용한 이유가 방문하는 그래프로 풀었기 때문에...
새해 첫 날 부터 문제도 풀었으니 새해 복 많이 받아야겠다~
반응형
'Algorithm > BAEKJOON' 카테고리의 다른 글
[백준/C++] 새로운 하노이 탑 (No. 12906) (0) | 2025.01.17 |
---|---|
[백준/C++] 크리스마스 선물 (No.14235) (0) | 2024.12.26 |
[백준/C++] 벌집들 (No. 3805) (0) | 2024.12.25 |
[백준/C++] 다음 팰린드롬 수 (No. 1334) (0) | 2024.12.16 |
[백준/C++] 급상승 (No. 23978) (0) | 2024.12.15 |