BZOJ 1297 迷路(矩阵)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1297

题意:给出一个带权有向图,权值为1-9,顶点个数最多为10。从1出发恰好在T时刻到达n的路径有多少条?

思路:T较大,应使用矩阵。矩阵要求边权为1.因此,将每个点i拆为9个点,i1到i9,前一个向后一个连边1。对于原图中的边<u,v,w>,u拆完后的第w个点向v拆完后第一个点连边1。求矩阵T次幂即可。

#include <iostream>
#include <cstdio>
#include <string.h>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <map>

#define abs(x) ((x)>=0?(x):-(x))
#define i64 long long
#define u32 unsigned int
#define u64 unsigned long long
#define clr(x,y) memset(x,y,sizeof(x))
#define CLR(x) x.clear()
#define ph(x) push(x)
#define pb(x) push_back(x)
#define Len(x) x.length()
#define SZ(x) x.size()
#define PI acos(-1.0)
#define sqr(x) ((x)*(x))

#define FOR0(i,x) for(i=0;i<x;i++)
#define FOR1(i,x) for(i=1;i<=x;i++)
#define FOR(i,a,b) for(i=a;i<=b;i++)
#define FORL0(i,a) for(i=a;i>=0;i--)
#define FORL1(i,a) for(i=a;i>=1;i--)
#define FORL(i,a,b)for(i=a;i>=b;i--)

#define rush() int C; for(scanf("%d",&C);C--;)
#define Rush(n)  while(scanf("%d",&n)!=-1)
using namespace std;

void RD(int &x){scanf("%d",&x);}
void RD(i64 &x){scanf("%lld",&x);}
void RD(u32 &x){scanf("%u",&x);}
void RD(double &x){scanf("%lf",&x);}
void RD(int &x,int &y){scanf("%d%d",&x,&y);}
void RD(u32 &x,u32 &y){scanf("%u%u",&x,&y);}
void RD(double &x,double &y){scanf("%lf%lf",&x,&y);}
void RD(int &x,int &y,int &z){scanf("%d%d%d",&x,&y,&z);}
void RD(u32 &x,u32 &y,u32 &z){scanf("%u%u%u",&x,&y,&z);}
void RD(double &x,double &y,double &z){scanf("%lf%lf%lf",&x,&y,&z);}
void RD(char &x){x=getchar();}
void RD(char *s){scanf("%s",s);}
void RD(string &s){cin>>s;}

void PR(int x) {printf("%d\n",x);}
void PR(i64 x) {printf("%lld\n",x);}
void PR(u32 x) {printf("%u\n",x);}
void PR(double x) {printf("%.4lf\n",x);}
void PR(char x) {printf("%c\n",x);}
void PR(char *x) {printf("%s\n",x);}
void PR(string x) {cout<<x<<endl;}

const int mod=100000007;
const i64 inf=((i64)1)<<40;
const double dinf=1000000000000000000.0;
const int INF=2000000000;
const int HASHSIZE=100007;
const int N=1000005;

int n,m;

struct Matrix
{
    int a[95][95];
    
    void init(int x)
    {
        clr(a,0);
        int i;
        if(x==1) 
        {
            FOR1(i,n) a[i][i]=1;
        }
    }
    
    Matrix operator*(Matrix p)
    {
        Matrix ans;
        ans.init(0);
        int i,j,k;
        FOR1(k,n) FOR1(i,n) FOR1(j,n)
        {
            ans.a[i][j]+=a[i][k]*p.a[k][j];
            ans.a[i][j]%=2009;
        }
        return ans;
    }
    
    Matrix pow(int m)
    {
        Matrix ans,p=*this;
        ans.init(1);
        while(m)
        {
            if(m&1) ans=ans*p;
            p=p*p;
            m>>=1;
        }
        return ans;
    }
};

Matrix a;
char s[15][15];

int cal(int x,int y)
{
    return (x-1)*9+y;
}

int main()
{
    RD(n,m);
    int i;
    FOR1(i,n) RD(s[i]+1);
    a.init(0);
    int j;
    FOR1(i,n)
    {
        FOR1(j,8) a.a[cal(i,j)][cal(i,j+1)]=1;
    }
    FOR1(i,n) FOR1(j,n) if(s[i][j]!='0')
    {
        a.a[cal(i,s[i][j]-'0')][cal(j,1)]=1;
    }
    n*=9;
    a=a.pow(m);
    int ans=a.a[cal(1,1)][cal(n/9,1)];
    PR(ans);
}

上一篇:淘宝--印风 专注于MySQL内核代码


下一篇:css-缩写