zoukankan      html  css  js  c++  java
  • 【bzoj1875】【JZYZOJ1354】[SDOI2009]HH去散步 矩阵快速幂 点边转换

    http://172.20.6.3/Problem_Show.asp?id=1354

    题意:求从起始点到终点走过的路程为x有多少种走法,不保证两点间只有一条路,刚走完一条路时不能原路返回,每条路长度为1。
     
    把每条路更换为正反两条边,再造一条出到起点的边s造一条入为终点的边t,将每一条边作为邻接矩阵中的点,矩乘即可
    注意题意告诉我们一条路中的正反两条边不能相连。
     
    代码
     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 const int maxn=10010;
     5 const double eps=1e-8;
     6 const int modn=45989;
     7 int n,m,d,s,t;
     8 struct mat{
     9     long long e[130][130];
    10     mat(){ memset(e,0,sizeof(e)); }
    11 };mat a;
    12 struct nod{
    13     int y;
    14     int f;
    15     int rev;
    16     int next;
    17 }e[200];
    18 int tot=0;
    19 int head[50]={};
    20 mat Mul(mat x,mat y){
    21     mat z;
    22     for(int i=0;i<=m*2+1;i++){
    23         for(int j=0;j<=m*2+1;j++){
    24             for(int k=0;k<=m*2+1;k++){
    25                 z.e[i][j]+=x.e[i][k]*y.e[k][j];
    26                 z.e[i][j]%=modn;
    27             }
    28         }
    29     }
    30     return z;
    31 }
    32 mat Pow(mat x,int k){
    33     mat z;
    34     for(int i=0;i<=m*2+1;i++){
    35         z.e[i][i]=1;
    36     }
    37     while(k>0){
    38         if(k&1){
    39             z=Mul(z,x);
    40         }
    41         x=Mul(x,x);
    42         k/=2;
    43     }
    44     return z;
    45 }
    46 void init(int x,int y,int rev){
    47     e[++tot].y=y;
    48     e[tot].next=head[x];
    49     e[tot].rev=rev;
    50     head[x]=tot;
    51 }
    52 void dfs(int x,int v){
    53     int y;
    54     if(x==t){
    55         a.e[v][2*m+1]=1;
    56     }
    57     for(int i=head[x];i;i=e[i].next){
    58         y=e[i].y;
    59         if(v!=e[i].rev){
    60             a.e[v][i]=1;
    61         }
    62         if(!e[i].f){
    63             e[i].f=1;
    64             dfs(y,i);
    65         }
    66     }
    67 }
    68 int main(){
    69     scanf("%d%d%d%d%d",&n,&m,&d,&s,&t);
    70     s+=1,t+=1;
    71     int x,y;
    72     for(int i=1;i<=m;i++){
    73         scanf("%d%d",&x,&y);
    74         init(x+1,y+1,tot+2);
    75         init(y+1,x+1,tot);
    76     }dfs(s,0);
    77     mat z=Pow(a,d+1);
    78     printf("%lld
    ",z.e[0][2*m+1]);
    79     return 0;
    80 }
    View Code
  • 相关阅读:
    汉罗塔问题
    有进度条圆周率计算
    turtle库笔记
    OwnCloud建立属于自己私有的云存储网盘
    HTTP 常见请求状态码
    虚拟机部署Kubernetes集群
    常用文件头(16进制)
    配置LAMP环境
    Linux系统日志
    Java的socket通信与操作系统的SocketAPI关系探究
  • 原文地址:https://www.cnblogs.com/137shoebills/p/7786498.html
Copyright © 2011-2022 走看看