본문 바로가기

백준

12916 K-Path

인접행렬! 대1 수학시간에 배운 개념이 나와서 신기했다. 그런데 행렬 어떻게 구현할지 몰라서 행렬 구현은 참고해서 풀었다. 

경로 경우의 수 문제를 이렇게 풀 수 있구나 재밌다

#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <functional>
#include <string>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <cmath>
#include <cstring>
#include <bitset>

#define xx first
#define yy second
#define all(x) (x).begin(), (x).end()

using namespace std;
using i64 = long long int;
using ii = pair<int, int>;
using ii64 = pair<i64, i64>;

using matrix = vector<vector<long long>>;
const int MOD = 1e9 + 7;

matrix operator * (matrix const& a, matrix const& b) {
	matrix ret(a.size(), vector<long long>(b[0].size()));
	for (int i = 0; i < a.size(); i++) 
	    for (int j = 0; j < b.size(); j++) 
	        for (int k = 0; k < b[0].size(); k++) {
		        ret[i][k] = (ret[i][k] + a[i][j] * b[j][k]) % MOD;
	}
	return ret;
}

matrix ipow(matrix map, int x)
{
    if (x == 0) {
        matrix one(map.size(), vector<long long>(map.size()));
        for (int i = 0; i < map.size(); i++) 
            one[i][i] = 1;
        return one;
    }

    matrix half = ipow(map, x / 2);
    half = half * half;

    if (x % 2 == 0)
        return half;

    return half * map;
}

int     main()
{
    int n, k;
    scanf("%d %d", &n, &k);
    
    matrix map(n, vector<long long>(n));
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            scanf("%d", &map[i][j]);
        }
    }
    
    map = ipow(map, k);
    int ans = 0;
    for (int i = 0; i < n; i++) 
        for (int j = 0; j < n; j++) 
            ans = (ans + map[i][j]) % MOD;
	printf("%d", ans);

    return 0;
}

'백준' 카테고리의 다른 글

12850 본대 산책2  (0) 2021.07.17
16938 캠프 준비  (0) 2021.07.17
11423 Primes  (0) 2021.05.15
20300 서강 근육 맨  (0) 2021.05.15
2042 구간 합 구하기  (0) 2021.05.08