zoukankan      html  css  js  c++  java
  • bzoj1898 [Zjoi2005]Swamp 沼泽鳄鱼——矩阵快速幂

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1898

    求到达方案数...还是矩阵快速幂;

    能够到达就把邻接矩阵那里赋成1,有鳄鱼的地方从各处来的路径都是0;

    因为时间周期只有2,3,4,所以每12个时间就是一个循环;

    可以用矩阵快速幂做了。

    一开始写了个一团糟,也不明白样例为什么输出0了...

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    typedef long long ll;
    int const mod=10000;
    int n,m,st,ed,K,head[55],ct,nf,ey[25][5],te[25],ans[55],tmp[55];
    struct E{
        int to,next; 
        E(int t=0,int n=0):to(t),next(n) {}
    }edge[2505];
    struct Matrix{
        int a[55][55];
        Matrix operator * (const Matrix &y) const
        {
            Matrix x;
            memset(x.a,0,sizeof x.a);
            for(int i=1;i<=n;i++)
                for(int k=1;k<=n;k++)
                    for(int j=1;j<=n;j++)
                        (x.a[i][j]+=a[i][k]*y.a[k][j])%=mod;
            return x;
        }
    }s[15],b;
    void add(int x,int y){edge[++ct]=E(y,head[x]); head[x]=ct;}
    void build1()
    {
        for(int x=1;x<=n;x++)
            for(int i=1;i<=12;i++)
                for(int j=head[x],u;j;j=edge[j].next)
                    s[i].a[x][u=edge[j].to]=1;//
    }
    void build2()
    {
        for(int i=1;i<=nf;i++)
            for(int t=1;t<=12;t++)
                for(int j=1;j<=n;j++)
                {
                    int x=ey[i][t%te[i]];
        //            for(int k=head[x],y;k;k=edge[k].next)
        //                s[j].a[y=edge[k].to][x]=0;
                    s[t].a[j][x]=0;
                }
    }
    //void init(Matrix &x)
    //{
    //    memset(x.a,0,sizeof x.a);
    //    for(int i=1;i<=55;i++)
    //        for(int j=55;j;j--)
    //            x.a[i][j]=1;
    //}
    void mul2(int a[55],int b[55][55],int c[55])
    {
        int tmp[55];
            for(int j=0;j<n;j++)
            {
                tmp[j]=0;
                for(int k=0;k<n;k++)
                   tmp[j]=(tmp[j]+a[k]*b[k][j])%mod;
            }
            for(int j=0;j<n;j++)
                c[j]=tmp[j];
    }
    int main()
    {
        scanf("%d%d%d%d%d",&n,&m,&st,&ed,&K);
        st++; ed++;
        for(int i=1,x,y;i<=m;i++)
        {
            scanf("%d%d",&x,&y);
            x++; y++;
            add(x,y); add(y,x);
        }
        scanf("%d",&nf);
        for(int i=1;i<=nf;i++)
        {
            scanf("%d",&te[i]);
            for(int j=1;j<=te[i];j++)
                scanf("%d",&ey[i][j]),ey[i][j]++;
        }
        build1(); build2();
    //    init(s[13]);
        for(int i=1;i<=n;i++)
            b.a[i][i]=s[13].a[i][i]=1;
        for(int i=1;i<=12;i++)s[13]=s[13]*s[i];
    //    Matrix b; init(b);
        int t=K/12;
        while(t)
        {
            if(t&1)b=b*s[13];
            s[13]=s[13]*s[13];
            t>>=1;
        }
        t=K%12;
        for(int i=1;i<=t;i++)b=b*s[i];
    //    for(int i=1;i<=55;i++)
    //        for(int j=1;j<=55;j++)
    //            if(b.a[i][j])printf("b:%d
    ",b.a[i][j]);
    //    tmp[st]=1;
    //    for(int i=1;i<=n;i++)
    //        for(int j=1;j<=n;j++)
    //            (ans[i]+=tmp[j]*b.a[j][i])%=mod;
        ans[st]=1;
        mul2(ans,b.a,ans);
        printf("%d",ans[ed]);
        return 0;
    }

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    typedef long long ll;
    int const mod=10000;
    int n,m,st,ed,K,nf,ey[5];
    struct Matrix{
        int a[55][55];
        Matrix operator * (const Matrix &y) const
        {
            Matrix x;
            memset(x.a,0,sizeof x.a);
            for(int i=1;i<=n;i++)
                for(int k=1;k<=n;k++)
                    for(int j=1;j<=n;j++)
                        (x.a[i][j]+=a[i][k]*y.a[k][j])%=mod;
            return x;
        }
        Matrix(){memset(a,0,sizeof a);}//
        void init()
        {
            for(int i=1;i<=n;i++) a[i][i]=1;
        }
    }s[15],b;
    Matrix operator ^ (Matrix a,int k)
    {
        Matrix ret; ret.init();
        while(k)
        {
            if(k&1)ret=ret*a;
            a=a*a;
            k>>=1;
        }
        return ret;
    }
    int main()
    {
        scanf("%d%d%d%d%d",&n,&m,&st,&ed,&K);
        st++; ed++;
        for(int i=1,x,y;i<=m;i++)
        {
            scanf("%d%d",&x,&y);
            x++; y++;
            for(int j=1;j<=12;j++)
                s[j].a[x][y]=s[j].a[y][x]=1;
        }
        scanf("%d",&nf);
        for(int i=1,tt;i<=nf;i++)
        {
            scanf("%d",&tt);
            for(int j=1;j<=tt;j++)
                scanf("%d",&ey[j]),ey[j]++;
            for(int j=1;j<=12;j++)
                for(int k=1;k<=n;k++)
                    s[j].a[k][ey[j%tt+1]]=0;//+1
        }
        s[13].init();
        for(int i=1;i<=12;i++)s[13]=s[13]*s[i];
        b=s[13]^(K/12);
        for(int i=1;i<=K%12;i++)b=b*s[i];
        printf("%d",b.a[st][ed]);
        return 0;
    }
  • 相关阅读:
    VS.NET2013发布网站的时候去掉.cs文件(预编译)(转)
    vs2013发布网站合并程序是出错(ILmerge.merge:error)
    转:c# Linq 的分页[转]
    AStar 路径规划之初级二
    ASttar 路径规划之初级
    AttributeError: module 'tensorflow' has no attribute 'set_random_seed'
    github提示Permission denied (publickey),如何才能解决?
    机器学习-模型评价指标
    pcl-qt使用QVTKWidget 与PCLVisualizer 显示雷达点云
    pcl-设置多线段宽度和颜色
  • 原文地址:https://www.cnblogs.com/Zinn/p/9206621.html
Copyright © 2011-2022 走看看