zoukankan      html  css  js  c++  java
  • [SDOI2009]HH去散步 矩阵乘法

    ~~~题面~~~

    题解:

      很久之前做的这道题,今天看差点没看懂QAQ,赶紧来记录一下。

      考虑f[i][j]表示i和j是否右边相连,有为1,否则为0,那么f同时可以表示从每个点出发走一步到其他点的方案数。

      于是用一个和f长得一模一样的矩阵g来表示从每个点出发到其他点的方案数。

      那么考虑g如何转移。

      其实只要用g*f就可以表示一次转移了。

      为什么?

      设当前转移到了第t次,则g[i][j]表示i到j走t-1次的方案数(因为还没有更新)

      那么矩阵乘法做了什么?

      $g[i][j] = sum_{l =1}^{n}{g[i][l] * f[l][j]}$

      也就是它枚举了点i走了t - 1次到l,然后再从l走一次到j的方案数。

      是否能转移则要看l 到 j是否有边,而f[l][j]的意义刚好就是这样。

      所以这其实就是做了一个DP,并用矩阵加速。

      但是题目有限制,不能反复走一条边,但我们用点来表示状态显然无法对此做出限制,因此考虑直接用边来设状态。

      g[i][j]表示从边i走到边j的方案数,一个边i可以走到j,当且仅当i的终点是j的起点。

      为了满足题目的限制,我们需要将一条无向边拆分为两条有向边。然后满足上述条件则g[i][j] = 1。

      然后当i是j的反向边时,g[i][j] = 0;

      直接快速幂优化,获得最后的答案只需要再枚举一下哪些边可以到达终点即可

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define R register int 
      4 #define AC 200
      5 #define ACway 5000
      6 #define mod 45989
      7 int n,m,t,A,B,have,answer;
      8 int date[ACway],Next[ACway],Head[AC],tot=1;//变tot为1开始以查询一条边的起点
      9 /*ans:一行,若A可直达(边)则为1,
     10 f:tot*tot 对于每列j而言,若行i满足:date[i](终点) == date[j^1](起点),则为1
     11 have=t-1(第一次已经在ans上了)
     12 因为是用边来转移和判断,所以最后要扫描一遍ans:
     13 若此边可达B,则answer+=ans.s[1][i]
     14 由于习惯问题,,,所有点一开始都+1*/
     15 
     16 struct matrix{
     17     int s[AC][AC];
     18 }ans,f,box;
     19 
     20 inline int read()
     21 {
     22     int x=0;char c=getchar();
     23     while(c>'9' || c<'0') c=getchar();
     24     while(c>='0' && c<='9') x=x*10+c-'0',c=getchar();
     25     return x;
     26 }
     27 
     28 inline void add(int f,int w)
     29 {
     30     date[++tot]=w,Next[tot]=Head[f],Head[f]=tot;
     31     date[++tot]=f,Next[tot]=Head[w],Head[w]=tot;//变无向为有向
     32 }
     33 
     34 void count(matrix x,matrix y)
     35 {
     36     for(R i=1;i<=tot;i++)
     37     {
     38         for(R j=1;j<=tot;j++)
     39         {
     40             box.s[i][j]=0;
     41             for(R l=1;l<=tot;l++)
     42                 box.s[i][j]=(box.s[i][j] + x.s[i][l] * y.s[l][j])%mod;
     43         }
     44     }
     45 }
     46 
     47 void qpow()
     48 {
     49     while(have)
     50     {
     51         if(have & 1) 
     52         {
     53             count(ans,f);
     54             ans=box;
     55         }
     56         have>>=1;
     57         count(f,f);
     58         f=box;
     59     }
     60 }
     61 
     62 void pre()
     63 {
     64     int a,b;
     65     n=read(),m=read(),t=read(),A=read()+1,B=read()+1;
     66     for(R i=1;i<=m;i++)
     67     {
     68         a=read()+1,b=read()+1;
     69         add(a,b);
     70         if(a == A)//如果A可以直达的话
     71             ans.s[1][tot^1]=1;
     72         else if(b == A) ans.s[1][tot]=1;
     73     }
     74     for(R j=2;j<=tot;j++)//枚举列
     75         for(R i=2;i<=tot;i++)//枚举行
     76             if(date[i] == date[j^1] && i != (j^1)) //error!!!这里要判断不是反向边才行,因为一个边的起点就等与反向边的终点啊
     77             //{
     78                 f.s[i][j]=1;
     79             //    printf("%d ---> %d
    ",i,j);
     80             //}
     81 /*    printf("ans:
    ");
     82     for(R i=2;i<=tot;i++)
     83         printf("%d ",ans.s[1][i]);
     84     printf("
    f:
    ");
     85     for(R i=2;i<=tot;i++)
     86     {
     87         for(R j=2;j<=tot;j++)
     88             printf("%d ",f.s[i][j]);
     89         printf("
    ");    
     90     }*/
     91     have=t-1;
     92 }
     93 
     94 void work()
     95 {
     96     for(R i=2;i<=tot;i++)
     97         if(date[i] == B) answer+=ans.s[1][i];
     98     answer%=mod;
     99     printf("%d
    ",answer);
    100 }
    101 
    102 int main()
    103 {
    104 //    freopen("in.in","r",stdin);
    105     pre();
    106     qpow();
    107     work();
    108 //    fclose(stdin);
    109     return 0;
    110 }
  • 相关阅读:
    vue路由传参页面刷新参数丢失问题解决方案
    理解MVC,MVP 和 MVVM
    HTTPS用的是对称加密还是非对称加密?
    元素显示隐藏的9种思路
    CSS中层叠上下文
    DOM盒模型和位置 client offset scroll 和滚动的关系
    css重点知识和bug解决方法
    你可能不知道的CSS
    如何在 React 中优雅的写 CSS?
    html5不常用标签应用场景
  • 原文地址:https://www.cnblogs.com/ww3113306/p/9561510.html
Copyright © 2011-2022 走看看