收集数码晶体

Problem Description
数码世界的国王Shoutmon想要在n个小岛上举办一个游戏,来让数码宝贝们好好玩耍。背景是这样的:在这n个小岛之间事先安放了一些单向通道,每个通道连接两个不同的小岛,且只能按一个给定的方向通过。数码宝贝每次由通道到达一个小岛时都会令体内增加一个“数码晶体”。

Shoutmon制定了一项规则,即数码宝贝们可以从某个小岛出发,到达一个目的小岛,如果到达目的小岛后体内的“数码晶体”数量恰好为L,那么此时可以在小岛上的兑奖处领取奖品(领完奖品后自动退出游戏)。注意,到达目的小岛后如果“数码晶体”数量不足,那么仍然可以离开小岛,直到某次回到目的小岛时“数码晶体”的数量恰好为L。每个小岛(包括起始小岛和目的小岛)与每条通道都不限制到达和通过次数。初始状态下体内的“数码晶体”数量为0。

为了保证活动正常进行,Shoutmon想要知道,有多少条路径可以从起始小岛S到达目的小岛T并领奖(可能有多次查询)。

Input
每个输入文件中一组数据。

第一行三个整数n、m、L(2<=n<=30,0<=m<=n(n-1),1<=L<=100),分别代表小岛个数、单向通道条数、恰好需要的“数码晶体”数。

接下来m行,每行两个整数u和v,代表从小岛u到小岛v有一条单向通道(假设小岛编号为从0到n-1)。数据保证u不等于v,且相同的有序对(u,v)最多出现一次。

然后一个正整数k(k<=nn),表示查询次数。

接着k行,每行两个整数S和T,表示需要查询有多少条路径可以从起始小岛S到达目的小岛T并领奖。

Output
输出k行,每行一个整数,对应查询的结果,即从起始小岛到达目的小岛并领奖的路径条数。由于路径条数可能很多,因此将结果模上1000000007。

Sample Input
3 4 4
0 1
0 2
1 2
2 0
3
1 1
0 2
2 0
Sample Output
0
2
1
Author
Shoutmon

/*对于有向图的邻接矩阵A,A^L中的元素aij为vi到vj长度为L的通路数*/
#include <iostream>
#include <cstdio>
using namespace std;
typedef long long llt;
const llt mod=1000000007;
llt A[32][32],Ans[32][32],Temp[32][32];
llt n,m,L,k;
void solve()
{
    for(llt l=0;l<L;++l)
    {
        for(llt i=0;i<n;++i)
        {
            for(llt j=0;j<n;++j)
            {
                Temp[i][j]=0;
                for(llt k=0;k<n;++k)
                {
                    Temp[i][j]+=(A[i][k]*Ans[k][j])%mod;
                    Temp[i][j]%=mod;
                }
            }
        }
        for(llt i=0;i<n;++i)
            for(llt j=0;j<n;++j) Ans[i][j]=Temp[i][j]%mod;
    }
}
int main()
{
    scanf("%lld %lld %lld",&n,&m,&L);
    for(llt i=0;i<m;++i)
    {
        llt u,v;
        scanf("%lld %lld",&u,&v);
        A[u][v]=1;
    }
    for(llt i=0;i<n;++i)
        Ans[i][i]=1;
    solve();
    scanf("%lld",&k);
    while(k--)
    {
        llt u,v;
        scanf("%lld %lld",&u,&v);
        printf("%lld\n",Ans[u][v]);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值