https://www.acmicpc.net/problem/12916
12916번: K-Path
첫 번째 줄에 N, K ( 1 ≤ N ≤ 100, 1 ≤ K ≤ 109) 이 공백을 구분으로 주어진다. 다음 N개의 줄에 걸쳐 민호가 작성한 인접 행렬이 주어진다. i번 줄의 j번 수가 1이면 i번 마을과 j번 마을의 길이 있
www.acmicpc.net
글에서 제공하는 건 정확히 인접행렬의 정의와 같습니다.
따라서 행렬을 입력 받아 $K$ 제곱해주고, 각 요소의 값들을 전부 더해주면 길이가 $K$ 인 경로의 수가 됩니다.
( 기본 이론 3 )
제 코드는 다음과 같습니다.
#include <stdio.h>
#define mod 1000000007
typedef struct {
long long array[100][100];
} Matrix;
Matrix matrix_multiply_modular (Matrix A, Matrix B, int size);
Matrix matrix_power_modular (Matrix Base, int size, int power);
int main() {
int size, power;
scanf("%d %d", &size, &power);
Matrix Base;
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
scanf("%lld", &Base.array[i][j]);
}
}
Base = matrix_power_modular (Base, size, power);
long long count = 0;
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
count += Base.array[i][j];
}
}
printf("%lld", count % mod);
return 0;
}
Matrix matrix_multiply_modular (Matrix A, Matrix B, int size) {
Matrix result = { {{0}} };
for (int i = 0; i < size; i++) {
for (int k = 0; k < size; k++) {
for (int j = 0; j < size; j++) {
result.array[i][j] = (result.array[i][j] + A.array[i][k] * B.array[k][j]) % mod;
}
}
}
return result;
}
Matrix matrix_power_modular (Matrix Base, int size, int power) {
Matrix result = { {{0}} };
for (int i = 0; i < size; i++) {
result.array[i][i] = 1;
}
while(power) {
if (power & 1) {
result = matrix_multiply_modular (result, Base, size);
}
Base = matrix_multiply_modular (Base, Base, size);
power >>= 1;
}
return result;
}
(C11, 1620KB, 80ms, 제출번호 31669642)
'분할 정복을 이용한 거듭제곱 > 행렬 거듭제곱' 카테고리의 다른 글
백준 12850번: 본대 산책2 (0) | 2021.08.01 |
---|---|
백준 2099번: The game of death (0) | 2021.07.31 |
백준 3827번: 일차원 세포 자동자 (0) | 2021.07.31 |
백준 15999번: 뒤집기 (0) | 2021.07.30 |
백준 13976번: 타일 채우기 2 (0) | 2021.07.30 |