[SDOI 2009] HH去散步

[题目链接]

         https://www.lydsy.com/JudgeOnline/problem.php?id=1875

[算法]

         用f[i][j]表示现在在走了i步 , 在第j条边的方案数

         矩阵加速 , 即可

         时间复杂度 : O(N ^ 3logN)

[代码]

         

#include<bits/stdc++.h>
using namespace std;
#define MAXN 125
const int P = 45989;

struct edge
{
        int to , nxt;
} e[MAXN << 1];
int n , m , t , A , B , tot;
int head[MAXN];

struct matrix_t
{
        int mat[MAXN][MAXN];    
} a , b;
template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
template <typename T> inline void read(T &x)
{
    T f = 1; x = 0;
    char c = getchar();
    for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
    for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
    x *= f;
}
inline void addedge(int u,int v)
{
        tot++;
        e[tot] = (edge){v , head[u]};
        head[u] = tot;
}
inline void multipy(matrix_t &a , matrix_t b)
{
        static matrix_t ret;
        for (int i = 1; i <= tot; i++)
        {
                for (int j = 1; j <= tot; j++)
                {
                        ret.mat[i][j] = 0;
                }
        }
        for (int i = 1; i <= tot; i++)
        {
                for (int j = 1; j <= tot; j++)
                {
                        for (int k = 1; k <= tot; k++)
                        {
                                ret.mat[i][j] = (ret.mat[i][j] + 1LL * a.mat[i][k] * b.mat[k][j]) % P; 
                        }
                }
        }
        a = ret;
}
inline void exp_mod(matrix_t &a , int t)
{
        static matrix_t tmp;
        for (int i = 1; i <= tot; i++)
        {
                for (int j = 1; j <= tot; j++)
                {
                        tmp.mat[i][j] = (i == j);
                }
        }
        while (t > 0)
        {
                if (t & 1) multipy(tmp , a);
                multipy(a , a);
                t >>= 1;
        }        
        a = tmp;
}

int main()
{
        
        read(n); read(m); read(t); read(A); read(B);
        ++A; ++B;
        tot = 1;
        for (int i = 1; i <= m; i++)
        {
                int u , v;
                read(u); read(v);
                ++u; ++v;
                addedge(u , v);
                addedge(v , u);
        }
        for (int i = 2; i <= tot; i++)
        {
                for (int j = 2; j <= tot; j++)
                {
                        if (i != (j ^ 1) && e[j ^ 1].to == e[i].to)
                                ++b.mat[i][j];                
                }
        }
        for (int i = head[A]; i; i = e[i].nxt) ++a.mat[1][i];
        exp_mod(b , t - 1);
        multipy(a , b);
        int ans = 0;
        for (int i = head[B]; i; i = e[i].nxt) ans = (ans + 1LL * a.mat[1][i ^ 1]) % P;
        printf("%d
" , ans);
        
        return 0;
    
}
原文地址:https://www.cnblogs.com/evenbao/p/9858884.html