zoukankan      html  css  js  c++  java
  • SCOI2009 迷路

    传送门

    首先有一个结论:一个只有0,1的邻接矩阵,(f[i][j])表示第(i)点到第(j)点走1步的路径条数。那么这个矩阵的k次幂的(f[i][j])就表示第(i)点到第(j)点走k步的路径条数。

    这个可以用矩阵快速幂优化,不过图有边权怎么办?

    我们可以拆点。因为边权很小,所以可以把每个点都拆成9个点。这样每个拆开的点向下一个点连边,边权为1。最后一个点连向它通向的点的第一个点即可。

    结果就是起始点拆开的第一个点到终点拆开的第一个点的路径条数。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<iostream>
    #include<cmath>
    #include<set>
    #include<vector>
    #include<map>
    #include<queue>
    #define rep(i,a,n) for(int i = a;i <= n;i++)
    #define per(i,n,a) for(int i = n;i >= a;i--)
    #define enter putchar('
    ')
    #define fr friend inline
    #define y1 poj
    #define mp make_pair
    #define pr pair<int,int>
    #define fi first
    #define sc second
    #define pb push_back
    
    using namespace std;
    typedef long long ll;
    const int M = 10005;
    const int INF = 1000000009;
    const ll mod = 2009;
    const double eps = 1e-7;
    
    ll read() 
    {
        ll ans = 0,op = 1;char ch = getchar();
        while(ch < '0' || ch > '9') {if(ch == '-') op = -1;ch = getchar();}
        while(ch >= '0' && ch <= '9') ans = ans * 10 + ch - '0',ch = getchar();
        return ans * op;
    }
    
    ll n,T,k;
    char s[15][15];
    
    struct matrix
    {
       ll f[105][105];
       matrix(){memset(f,0,sizeof(f));}
       fr matrix operator * (const matrix &a,const matrix &b)
       {
          matrix c;
          rep(i,1,n)
         rep(j,1,n)
         rep(k,1,n) c.f[i][j] += a.f[i][k] * b.f[k][j],c.f[i][j] %= mod;
          return c;
       }
    }F;
    
    void build()
    {
       rep(i,1,n)
       {
          rep(j,1,8) F.f[(i-1)*9+j][(i-1)*9+j+1] = 1;
          rep(j,1,n) if(s[i][j] > '0') k = s[i][j] - '0',F.f[(i-1)*9+k][(j-1)*9+1] = 1;
       }
       n *= 9;
    }
    
    matrix mpow(matrix a,ll b)
    {
       matrix p;
       rep(i,1,n) p.f[i][i] = 1;
       while(b)
       {
          if(b&1) p = p * a;
          a = a * a,b >>= 1;
       }
       return p;
    }
    
    int main()
    {
       n = read(),T = read();
       rep(i,1,n) scanf("%s",s[i]+1);
       build();
       matrix d = mpow(F,T);
       printf("%lld
    ",d.f[1][n-8]);
       return 0;
    }
    
    
  • 相关阅读:
    TCP的三次握手与四次挥手理解及面试题(很全面)
    python解释器锁的理解
    Flask的基本使用、四剑客和配置文件
    Django cache缓存
    xadmin后台管理
    cookies与session
    Java stream流
    Java IO流
    springboot配置文件加载顺序与一些常用配置
    OAuth2.0开放授权
  • 原文地址:https://www.cnblogs.com/captain1/p/10147035.html
Copyright © 2011-2022 走看看