• 【BZOJ】1875: [SDOI2009]HH去散步


    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1875


    注意的是路径不可以重复,所以这题把边看成点。每一条无向边拆成两条有向边。

    令${F[t][i][j]}$表示从编号为$i$的边走到编号为$j$的边走了$t$步的边集个数。

    ${F[t][i][j]=sum f[i-1][i][k]*f[i-1][k][j]}$

    这不就是矩乘的形式么,矩乘优化DP即可。


     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<vector>
     5 #include<cstdlib>
     6 #include<cmath>
     7 #include<cstring>
     8 using namespace std;
     9 #define maxn 10010
    10 #define llg long long
    11 #define SIZE 126
    12 #define mod 45989
    13 #define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
    14 llg nn,m,A,B,last[maxn*10],t;
    15 llg cnt=1;
    16 struct MATRIX
    17 {
    18       llg mt[SIZE][SIZE];
    19       llg x,y;
    20     void init(){memset(mt,0,sizeof(mt)); x=y=0;}
    21 }ans,def;
    22 
    23 struct edge
    24 {
    25     llg from,to,next,v;
    26 }e[maxn*10];
    27 
    28 llg in_()
    29 {
    30     int x=0,f=1;char ch=getchar();
    31     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    32     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    33     return x*f;
    34 }
    35 
    36 inline MATRIX operator *(MATRIX a,MATRIX b)
    37 {
    38     MATRIX c;
    39     for (llg i=0;i<=cnt;i++) for (llg j=0;j<=cnt;j++) c.mt[i][j]=0;
    40     c.x=a.x; c.y=b.y;
    41     for(int i=1;i<=a.x;i++)
    42         for(int j=1;j<=b.y;j++)
    43             for(int k=1;k<=a.y;k++)
    44                 c.mt[i][j]=(c.mt[i][j]+(a.mt[i][k])*(b.mt[k][j]))%mod;
    45     return c;
    46 }
    47 
    48 void insert(llg v,llg u)
    49 {
    50     e[++cnt].to=v; e[cnt].from=u; e[cnt].next=last[u],last[u]=cnt;
    51     e[++cnt].to=u; e[cnt].from=v; e[cnt].next=last[v],last[v]=cnt;
    52 }
    53 
    54 int main()
    55 {
    56     yyj("bzoj1875");
    57     cin>>nn>>m>>t>>A>>B;
    58     for (llg i=1;i<=m;i++) insert(in_(),in_());
    59     MATRIX b;
    60     b.init();
    61     def.x=def.y=ans.x=ans.y=b.x=b.y=cnt;
    62     t--;
    63     for (llg i=2;i<=cnt;i++)
    64         for (llg j=2;j<=cnt;j++)
    65             if (e[i].to==e[j].from && i!=(j^1)) b.mt[i][j]++;
    66     for (llg i=1;i<=cnt;i++) ans.mt[i][i]=1;
    67     for (llg i=t;i;i>>=1,b=b*b) 
    68         if (i&1) 
    69             ans=ans*b;
    70     for (llg i=last[A];i;i=e[i].next) def.mt[1][i]++;
    71     ans=def*ans;
    72     llg sum=0;
    73     for (llg i=last[B];i;i=e[i].next) sum+=ans.mt[1][i^1];
    74     cout<<sum%mod;
    75     return 0;
    76 }
    本文作者:xrdog 作者博客:http://www.cnblogs.com/Dragon-Light/ 转载请注明出处,侵权必究,保留最终解释权!
  • 相关阅读:
    202020211 20209326 《Linux内核原理与分析》第一周作业
    指针入门,以及利用指针简单的数组逆置
    函数入门
    C语言关于处理数组元素的插入、删除、排序
    flag用法之一
    css3中的transform值matrix
    HTML5CANVAS做的打砖块游戏。。。
    用curl抓取网站数据,仿造IP、防屏蔽终极强悍解决方式
    javascript中最好用的extend继承方法
    使用CSS3中Media Queries兼容不同设备
  • 原文地址:https://www.cnblogs.com/Dragon-Light/p/6408416.html
Copyright © 2020-2023  润新知