반응형
https://www.acmicpc.net/problem/1533
1533번: 길의 개수
첫째 줄에 교차점의 개수 N이 주어진다. N은 10보다 작거나 같고, 시작점의 위치 S와 끝점의 위치 E, 그리고 정문이가 늦는 시간 T도 주어진다. S와 E는 N보다 작거나 같은 자연수이다. T는 1,000,000,000
www.acmicpc.net

[ 문제풀이 ]
가중치가 있는 행렬의 이동 가능한 경로의 개수를 구하기 위해서는 가중치가 없는(가중치가 1인) 행렬로 바꿔주어야 합니다.
가중치의 최댓값이 5이기 때문에 노드 하나를 5개로 나누어 가중치가 없는 행렬로 만듭니다.
예를 들어 u→v로 가는 데 걸리는 시간이 3이라면 u→v2→v1→v0을 통해 이동하면 됩니다.
[ 소스 코드 ]
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 | #include<iostream> #include<vector> #include<string> #include<unordered_map> #define M 1000003 #define ll long long using namespace std; int N, S, E, T; unordered_map<int, vector<vector<ll>>> m; vector<vector<ll>> vect(50, vector<ll>(50, 0)); vector<vector<ll>> multi(vector<vector<ll>> a, vector<vector<ll>> b) //행렬 곱셈 { vector<vector<ll>> ret(N * 5, vector<ll>(N * 5, 0)); for (int i = 0; i < N * 5; i++) { for (int j = 0; j < N * 5; j++) { int sum = 0; for (int k = 0; k < N * 5; k++) { sum += ((a[i][k] % M) * (b[k][j] % M))%M; sum %= M; } ret[i][j] = sum; } } return ret; } vector<vector<ll>> conquer(int num) //분할 정복 { if (m.count(num) != 0) return m[num]; if (num == 1) return vect; if (num % 2 == 1) { return m[num] = multi(conquer(num - 1), conquer(1)); } else { return m[num] = multi(conquer(num / 2), conquer(num / 2)); } } int main() { scanf("%d %d %d %d", &N, &S, &E, &T); vector<vector<ll>> ans; for (int i = 0; i < N; i++) { //입력 받은 가중치가 있는 행렬을 가중치가 없는 string str; //행렬로 바꾸기 cin >> str; for (int j = 0; j < N; j++) { int num = str[j] - '0'; if (num > 0) { vect[i * 5][j * 5 + num - 1] = 1; } for (int k = 0; k < 4; k++) { vect[j * 5 + k + 1][j * 5 + k] = 1; } } } ans = conquer(T); printf("%d", ans[(S - 1) * 5][(E - 1) * 5]); } | cs |
반응형
'백준' 카테고리의 다른 글
[ 백준 ] 11266번 - 단절점 (C++) (0) | 2022.08.27 |
---|---|
[ 백준 ] 3653번 - 영화 수집 (C++) (0) | 2022.08.25 |
[ 백준 ] 11286번 - 절댓값 힙 (C++) (0) | 2022.08.23 |
[ 백준 ] 3176번 - 도로 네트워크 (C++) (0) | 2022.08.22 |
[ 백준 ] 1780번 - 종이의 개수 (C++) (0) | 2022.08.21 |