zoukankan      html  css  js  c++  java
  • 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。
    N ≤ 20,M ≤ 60,t ≤ 2^30,0 ≤ A,B

    Output

    一行,表示答案。

    Sample Input

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

    Sample Output

    4

    第一道矩阵乘法……orz调了半天发现自己犯了一个傻逼错误
    多余的不解释了,学习笔记里有思路。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstdlib>
     4 #include<cstring>
     5 #define MOD (45989)
     6 using namespace std;
     7 struct Mar
     8 {
     9     int a[201][201];
    10 } unit,G;
    11 struct node1
    12 {
    13     int to,next;
    14 } edge[10001];
    15 int n,head[10001],num_edge;
    16 
    17 void add(int u,int v)
    18 {
    19     edge[num_edge].to=v;
    20     edge[num_edge].next=head[u];
    21     head[u]=num_edge++;
    22 }
    23 
    24 Mar Mul(Mar x,Mar y)
    25 {
    26     Mar c;
    27     memset(c.a,0,sizeof(c.a));//初始化,不然会GG 
    28     for (int i=0; i<=num_edge-1; ++i)
    29         for (int j=0; j<=num_edge-1; ++j)
    30             for (int k=0; k<=num_edge-1; ++k)
    31                 c.a[i][j]=(c.a[i][j]+x.a[i][k]*y.a[k][j])%MOD;
    32     return c;
    33 }
    34 
    35 Mar Mar_pow(Mar a,int p)
    36 {
    37     Mar ans=unit;
    38     while (p!=0)
    39     {
    40         if (p&1)
    41             ans=Mul(ans,a);
    42         a=Mul(a,a);
    43         p>>=1;
    44     }
    45     return ans;
    46 }
    47 
    48 int main()
    49 {
    50     int m,t,st,ed,u,v;
    51     scanf("%d%d%d%d%d",&n,&m,&t,&st,&ed);
    52     ++st;++ed;
    53     for (int i=1; i<=n; ++i) head[i]=-1;
    54     for (int i=1; i<=m; ++i)
    55     {
    56         scanf("%d%d",&u,&v);
    57         ++u;++v;
    58         add(u,v);add(v,u);
    59     }
    60     for (int i=0; i<=num_edge-1; ++i)
    61         unit.a[i][i]=1;//给单位矩阵赋值 
    62     for (int i=0; i<=num_edge-1; ++i)
    63         for (int j=head[edge[i].to]; j!=-1; j=edge[j].next)
    64             if ((i!=(j^1)))
    65                 G.a[i][j]++;
    66     
    67     G=Mar_pow(G,t-1);
    68     int Final=0;
    69     for (int i=head[st]; i!=-1; i=edge[i].next)
    70         for (int j=head[ed]; j!=-1; j=edge[j].next)
    71             Final=(Final+G.a[i][j^1])%MOD;//异或就是将二进制最后一位取反,即入边变出边,出边变入边 
    72     printf("%d",Final);
    73 }
  • 相关阅读:
    关于【缓存穿透、缓存击穿、缓存雪崩、热点数据失效】问题的解决方案
    pycharm快捷键
    php 整理的零碎知识点
    phpadmin 导出csv格式的数据处理
    python 单例模式的实现
    Java单体应用
    Java单体应用
    Java单体应用
    Java单体应用
    Java单体应用
  • 原文地址:https://www.cnblogs.com/refun/p/8678583.html
Copyright © 2011-2022 走看看