ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • UCPC 2020 C / 함수 복원 - 19544
    Algorithm/BOJ 2020. 8. 5. 23:02
    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
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    #include <iostream>
    #include <vector>
    using namespace std;
     
    const int MOD = 1000000007;
     
    int N;
    int arr[500][500];
    vector<int> cyidx;
    vector<vector<int>> cycleMem;
    vector<vector<int>> aroundMem;
    vector<long long> bucket;
     
    long long cal2(long long u, long long v) {
        long long ret = 1;
        while(v) {
            ret *= u;
            ret %= MOD;
            --v;
        }
        return ret;
    }
     
    long long cal(long long u, long long v) {
        
        long long ret = 1;
        while(v) {
            ret *= u;
            ret %= MOD;
            --u;
            --v;
        }
        return ret;
    }
     
    int main() {
        ios_base::sync_with_stdio(0), cin.tie(0);
        cin >> N;
        cyidx = vector<int>(N, -1);
        for(int i = 0; i<N; ++i)
            for(int j = 0; j<N; ++j)
                cin >> arr[i][j];
        
        for(int i = 0; i<N; ++i)
            for(int j = i+1; j<N; ++j) {
                if(arr[i][j] && arr[j][i]) {
                    if(cyidx[i] == -1 && cyidx[j] == -1) {
                        cycleMem.push_back(vector<int>());
                        cyidx[i] = cyidx[j] = cycleMem.size()-1;
                        cycleMem[cyidx[i]].push_back(i);
                        cycleMem[cyidx[i]].push_back(j);
                    }
                    else if(cyidx[j] == -1) {
                        cyidx[j] = cyidx[i];
                        cycleMem[cyidx[j]].push_back(j);
                    }
                }
            }
        aroundMem = vector<vector<int>>(cycleMem.size());
        for(int i = 0; i<cycleMem.size(); ++i) {
            int base = cycleMem[i][0];
     
            for(int j = 0; j<N; ++j) {
                if(cyidx[j] == -1 && arr[j][base]) {
                    int cnt = 0;
                    for(int k = 0; k<N; ++k)
                        if(arr[j][k]) ++cnt;
                    --cnt;
                    if(cnt == cycleMem[i].size())
                        aroundMem[i].push_back(j);
                }
            }
        }
     
        bucket = vector<long long>(cycleMem.size(), 1);
        for(int i = 0; i<cycleMem.size(); ++i) {
            long long res = cal(cycleMem[i].size() - 1, cycleMem[i].size() - 1);
            long long res2 = cal2(cycleMem[i].size(), aroundMem[i].size());
            bucket[i] = res*res2;
            bucket[i] %= MOD;
        }
        long long ans = 1;
        for(int i = 0; i<cycleMem.size(); ++i) {
            ans *= bucket[i];
            ans %= MOD;
        }
        cout << ans;
    }
    cs

     

     

     

     

     

     

    https://www.acmicpc.net/problem/19544

     

    19544번: 함수 복원

    자연수 $N$이 주어질 때, $1$ 이상 $N$ 이하의 자연수 $i$에 대해 정의되는 함수 $f$가 있다. 모든 $i$에 대해 $f\left(i\right)$ 또한 $1$ 이상 $N$ 이하의 자연수다. $f$에 대한 함수 그래프를 정점 $i$에서 정�

    www.acmicpc.net

     

     

     

     

     

     

    함수 복원

    함수들을 그래프로 표현한다면, 모든 노드에서 나가는 간선은 오직 1개인 노드들로 이루어진 그래프가 그려집니다.

    따라서 각각 연결된 그래프를 이루는 집합끼리 나누고,

    해당 집합 안에선 (싸이클을 이루는 노드들로 원에 줄 세우는 경우의 수) * (싸이클을 이루는 노드가 아닌 노드중 싸이클과 인접한 노드의 개수를 싸이클의 노드들에 각각 붙이는 경우의 수)

    를 구하고,

    집합 각각에서 구한 위의 값들을 모두 곱해주면 답이 됩니다.

     

     

     

     

     

    댓글

Designed by Tistory.