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


    题意:给出一个无向图,求s到t经过k条路的方案数,且不能存在从A到B再到A这样的路径

    用Floyd类型的矩阵乘法,不同的是这里的邻接矩阵是对于边的,这样就能防止走回来了

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    
    using namespace std;
    
    const int MAXN=64<<2;
    const int MOD=45989;
    struct Edge{
      int next,to,from;
    }e[MAXN<<1];
    int ecnt=1,head[MAXN];
    
    inline void add(int x,int y){
      e[++ecnt]={head[x],y,x};
      head[x]=ecnt;
    }
    
    struct Mat{
      int data[MAXN][MAXN];
      Mat(){memset(data,0,sizeof(data));}
      Mat operator*(const Mat &rhs){
        Mat ret;
        for(int k=2;k<=ecnt;k++)
          for(int i=2;i<=ecnt;i++)
            for(int j=2;j<=ecnt;j++)
              ret.data[i][j]=(ret.data[i][j]+data[i][k]*rhs.data[k][j])%MOD;
        return ret;
      }
      Mat operator^(int x){
        Mat ret;for(int i=2;i<=ecnt;i++)ret.data[i][i]=1;
        for(Mat base=*this;x;x>>=1){
          if(x&1) ret=ret*base;
          base=base*base;
        }
        return ret;
      }
    };
    
    int n,m,k,s,t;
    int mp[MAXN][MAXN];
    
    int main(){
      cin>>n>>m>>k>>s>>t;
      int x,y;s++;t++;
      for(int i=1;i<=m;i++){
        cin>>x>>y;x++;y++;
        add(x,y);add(y,x);
      }
      for(int i=2;i<=ecnt;i++){
        for(int j=2;j<=ecnt;j++){
          if(e[i].to==e[j].from&&(i!=(j^1))) mp[i][j]=1;
        }
      }
      Mat T,S;
      memcpy(T.data,mp,sizeof(mp));
      T=T^(k-1);
      for(int i=head[s];i;i=e[i].next){
        S.data[2][i]++;
      }
      S=S*T;
      int ans=0;
      for(int i=head[t];i;i=e[i].next){
        int v=i^1;
        ans+=S.data[2][v];ans%=MOD;
      }
      cout<<ans<<endl;
      return 0;
    }

    本文来自博客园,作者:GhostCai,转载请注明原文链接:https://www.cnblogs.com/ghostcai/p/9363204.html

  • 相关阅读:
    Oracle数据库五种约束
    Oracle中sql的基本使用
    暮光之城》剧本
    英语电影剧本大全(中英对照)
    加勒比海盗1英文剧本
    公主日记英文剧本
    教父2-英文版
    <老友记>学习笔记
    霍夫变换Hough
    景深(Depth of Field)
  • 原文地址:https://www.cnblogs.com/ghostcai/p/9363204.html
Copyright © 2020-2023  润新知