zoukankan      html  css  js  c++  java
  • bzoj 1875 [SDOI2009]HH去散步(矩乘)

     

    Description

    HH有个一成不变的习惯,喜欢饭后百步走。所谓百步走,就是散步,就是在一定的时间 内,走过一定的距离。 但是同时HH又是个喜欢变化的人,所以他不会立刻沿着刚刚走来的路走回。 又因为HH是个喜欢变化的人,所以他每天走过的路径都不完全一样,他想知道他究竟有多 少种散步的方法。 现在给你学校的地图(假设每条路的长度都是一样的都是1),问长度为t,从给定地 点A走到给定地点B共有多少条符合条件的路径

    Input

    第一行:五个整数N,M,t,A,B。其中N表示学校里的路口的个数,M表示学校里的 路的条数,t表示HH想要散步的距离,A表示散步的出发点,而B则表示散步的终点。 接下来M行,每行一组Ai,Bi,表示从路口Ai到路口Bi有一条路。数据保证Ai = Bi,但 不保证任意两个路口之间至多只有一条路相连接。 路口编号从0到N − 1。 同一行内所有数据均由一个空格隔开,行首行尾没有多余空格。没有多余空行。 答案模45989。

    Output

    一行,表示答案。

    Sample Input

    4 5 3 0 0
    0 1
    0 2
    0 3
    2 1
    3 2

    Sample Output

    4

    HINT

    对于30%的数据,N ≤ 4,M ≤ 10,t ≤ 10。
    对于100%的数据,N ≤ 20,M ≤ 60,t ≤ 230,0 ≤ A,B

    【思路】

          

           矩阵乘法,边点互换

           题目中有不能走回头路的要求但同时存在重边。边点互换一下就可以满足这个要求啦。按照边的连接构造A矩阵并求出A^(t-1),新建一个虚拟节点,使之向a的所有出边连通,B*A即可求出虚拟节点到各边长度为t的路径数,然后统计所有与b相连的边。

    【代码】

     1 #include<cmath>
     2 #include<queue>
     3 #include<vector>
     4 #include<cstdio>
     5 #include<cstring>
     6 #include<iostream>
     7 #include<algorithm>
     8 #define FOR(a,b,c) for(int a=(b);a<=(c);a++)
     9 using namespace std;
    10 
    11 const int maxn = 25*5;
    12 const int MOD = 45989;
    13 struct Edge { int v,next;
    14 }es[maxn<<1];
    15 
    16 struct Matrix {
    17     int r,c,N[maxn][maxn];
    18     void init(int r,int c) {
    19         this->r=r,this->c=c;
    20         memset(N,0,sizeof(N));
    21     }
    22     Matrix operator * (const Matrix B) const{
    23         Matrix C; C.init(r,B.c);
    24         for(int i=0;i<r;i++)
    25             for(int j=0;j<B.c;j++)
    26                 for(int k=0;k<c;k++)
    27                     C.N[i][j]=(C.N[i][j]+N[i][k]*B.N[k][j])%MOD;
    28         return C;
    29     }
    30     Matrix pow(int p) {
    31         Matrix tmp=*this,ans;
    32         ans.init(r,r);
    33         for(int i=0;i<r;i++) ans.N[i][i]=1;
    34         while(p) {
    35             if(p&1) ans=ans*tmp;
    36             tmp=tmp*tmp; p>>=1;
    37         }
    38         return ans;
    39     }
    40 }A,B;
    41 
    42 int n,m,t,a,b,u,v;
    43 int front[maxn],en=-1;
    44 void adde(int u,int v) {
    45     en++; es[en].next=front[u]; es[en].v=v; front[u]=en;
    46 }
    47 
    48 int main() {
    49     freopen("in.in","r",stdin);
    50     freopen("out.out","w",stdout);
    51     memset(front,-1,sizeof(front));
    52     scanf("%d%d%d%d%d",&n,&m,&t,&a,&b);
    53     for(int i=0;i<m;i++) {
    54         scanf("%d%d",&u,&v);
    55         adde(u,v),adde(v,u);
    56     }
    57     en+=3;
    58     A.init(en,en),B.init(en,en);
    59     for(int i=front[a];i>=0;i=es[i].next) B.N[en-2][i]=1;
    60     for(int i=0;i<n;i++) {
    61         for(int u=front[i];u>=0;u=es[u].next) {
    62             int j=es[u].v;
    63             for(int v=front[j];v>=0;v=es[v].next) 
    64                 if(u!=(v^1))  A.N[u][v]++;
    65         }
    66     }
    67     A=A.pow(t-1);
    68     A=B*A;
    69     int ans=0;
    70     for(int i=front[b];i>=0;i=es[i].next)
    71         ans=(ans+A.N[en-2][i^1])%MOD;
    72     printf("%d",ans);
    73     return 0;
    74 }
  • 相关阅读:
    Vue项目碰到"‘webpack-dev-server’不是内部或外部命令,也不是可运行的程序或批处理文件"报错
    PowerDesigner最基础的使用方法入门学习
    Centos7 上安装mysql遇上的问题:mysql无法正常启动
    微信小程序的Web API接口设计及常见接口实现
    模型数据作渲染优化时遇到的问题
    vertex compression所遇到的问题
    depth and distance
    Linear or non-linear shadow maps?
    实施vertex compression所遇到的各种问题和解决办法
    【转】編譯Ogre1.9 IOS Dependencies及Ogre Source步驟及相關注意事項…
  • 原文地址:https://www.cnblogs.com/lidaxin/p/5225071.html
Copyright © 2011-2022 走看看