How many ways??,题解

题目:

  

                                                                                                                          

题意:

  找过k条边的路径个数。

分析:

  首先注意一下题意,同一个点过两次算两次,做过类似的,过k条边的最短路,只要搞一个矩阵,然后快速幂就好了,这个也一样,维护信息变一下,然后就好了。

  如果k很大:

    并不影响此种做法。

  如果n很大:

    改成dp。dp[x][k]表示过k个边到点x的路径数,然后就可以了。

代码:

  

#include <cstdio>
#include <cstring>
#include <string>
using namespace std;
const int maxn=100+10;
const int maxm=20+10;
int ed[maxm][maxm];
int n;
struct JZ{
    int a[maxm][maxm];
    JZ(){
        memset(a,0,sizeof(a));
    }
    JZ(int s){
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                a[i][j]=ed[i][j];
    }
    JZ(int s,int k){
        memset(a,0,sizeof(a));
        for(int i=1;i<=n;i++)
            a[i][i]=1;
    }
    friend JZ operator + (JZ a,JZ b){
        JZ c;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                for(int k=1;k<=n;k++){ 
                    c.a[i][j]+=b.a[i][k]*a.a[k][j];
                    c.a[i][j]%=1000;
                }
        return c;
    }
};
int ha[maxn];
int main(){
    int N,m;
    while(~scanf("%d%d",&n,&m)&&(m||n)){
        memset(ed,0,sizeof(ed));
        int js1,js2;
        for(int i=1;i<=m;i++){
            scanf("%d%d",&js1,&js2);
            ed[js1+1][js2+1]=1;
        }
        int q;
        scanf("%d",&q);
        for(int i=1;i<=q;i++){
            scanf("%d%d%d",&js1,&js2,&N);
            bool f=1;
            JZ D(1,1);
            for(JZ now(1);N;now=now+now){
                if(N&1)
                    D=D+now;
                N>>=1;
            }
            printf("%d\n",D.a[js1+1][js2+1]);
        }
    }
    return 0;
}
扫描二维码关注公众号,回复: 11218427 查看本文章

猜你喜欢

转载自www.cnblogs.com/wish-all-ac/p/12909812.html