• bzoj1875: [SDOI2009]HH去散步


    矩阵乘法。

    关于点的无法表示刚才走过的路不能走,所以用把边拆成俩个来建图,自己不能和自己连。

    然后再用俩点表示起点和终点。

    快速幂求矩阵(t+1)次就可以了(t+1次是因为到达终点那条边就需要t次,然后新建了一个终点,就会多走一步)。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int maxn = 200;
    const int maxm = 200;
    const int mod = 45989;
    
    int u[maxm],v[maxm],next[maxm],eid;
    int n,m,t,p1,p2;
    
    void addedge(int a,int b) {
        u[eid]=a; v[eid]=b; eid++;//next[eid]=g[a]; g[a]=eid++;
        u[eid]=b; v[eid]=a; eid++;//next[eid]=g[b]; g[b]=eid++;
    }
    
    struct Matrix {
        int a[maxm][maxm];
        
        int* operator [] (int x) {
            return a[x];
        }
        
        Matrix operator * (Matrix b) {
            Matrix res;
            for(int i=0;i<=n;i++)
            for(int j=0;j<=n;j++)
            for(int k=0;k<=n;k++)
                res[i][k]=(res[i][k]+a[i][j]*b[j][k])%mod;
            return res;
        }
        
        Matrix operator ^ (int e) {
            Matrix res,tmp=*this;
            res.init();
            while(e) {
                if(e&1) res=res*tmp;
                tmp=tmp*tmp;
                e>>=1;
            }
            return res;
        }
        
        void init() {
            memset(a,0,sizeof(a));    
            for(int i=0;i<=n;i++) a[i][i]=1;
        }
        
        void debug() {
            for(int i=0;i<=n;i++) {
                for(int j=0;j<=n;j++) printf("%d ",a[i][j]);
                printf("
    ");    
            }
            
        }
        
        Matrix() {
            memset(a,0,sizeof(a));    
        }
    }s;
    
    int main() {
        scanf("%d%d%d%d%d",&n,&m,&t,&p1,&p2);
        
        for(int i=1,u,v;i<=m;i++) {
            scanf("%d%d",&u,&v);
            addedge(u,v);
        }
        
        for(int i=0;i<eid;i++)
        for(int j=0;j<eid;j++) 
            if(v[i]==u[j]&& (i!=(j^1))) {
                s[i][j]=1;        
                
        }
        for(int i=0;i<eid;i++) {
            if(u[i]==p1) s[eid][i]=1;
            if(v[i]==p2) s[i][eid+1]=1;        
        }
        n=eid+1;
        s=s^(t+1);
        printf("%d
    ",s[eid][eid+1]);
        return 0;
    }
  • 相关阅读:
    怎么把分页按钮(首页,尾页等)放在表格右下角处?(已解决)
    zabbix单位符号
    容器、可迭代对象、迭代器、生成器之间的关系.
    Zabbix housekeeper processes more than 75% busy
    zabbix 告警信息模板
    zabbix 历史数据和趋势数据
    socket沾包问题
    面向对象--进阶
    面向对象
    列表 元组 字典
  • 原文地址:https://www.cnblogs.com/invoid/p/5677091.html
Copyright © 2020-2023  润新知