洛谷P3758 [TJOI2017]可乐 (图的矩阵快速幂)

题目描述

加里敦星球的人们特别喜欢喝可乐。因而,他们的敌对星球研发出了一个可乐机器人,并且放在了加里敦星球的1号城市上。这个可乐机器人有三种行为: 停在原地,去下一个相邻的城市,自爆。它每一秒都会随机触发一种行为。现 在给加里敦星球城市图,在第0秒时可乐机器人在1号城市,问经过了t秒,可乐机器人的行为方案数是多少?

输入格式

第一行输入两个正整数况N,M,N表示城市个数,M表示道路个数。(1 <= N <=30,0 < M < 100)

接下来M行输入u,v,表示u,v之间有一条道路。(1<=u,v <= n)保证两座城市之间只有一条路相连。

最后输入入时间t

输出格式

输出可乐机器人的行为方案数,答案可能很大,请输出对2017取模后的结果。

输入输出样例

输入 #1复制

3 2
1 2
2 3
2

输出 #1复制

8

说明/提示

【样例解释】

1 ->爆炸

1 -> 1 ->爆炸

1 -> 2 ->爆炸

1 -> 1 -> 1

1 -> 1 -> 2

1 -> 2 -> 1

1 -> 2 -> 2

1 -> 2 -> 3

【数据范围】

对于20%的pn,有1 < t ≤ 1000

对于100%的pn,有1 < t ≤ 10^6。

题解

pgy said:这道题的唯一难一点的地方就是怎么处理“自爆”和“停在原地”

蒟蒻我看到题目就想起来了,然而,并不知道要用矩阵快速幂

似乎答案特别大的题目啦,要模一个数的题目啦,统计方案数的题目啦,就是矩阵快速幂优化DP的

然后我们看一下这道题:

以前有写过图的矩阵快速幂看这里

对于本题,我们可以把它当做从1开始,走t步恰好到达i (1<=i<=n)的方案数

已知G^^{k}[i][j]表示从i开始到j为止走了k步的路径数,是不是很显然了 qwq

最后还是说一下开始提到的   自爆  和  留在原地  的问题

自爆嘛 就是连一个到0的边(但是程序里写的好像是n+1,将就着看吧)这样就再也出不来了,像死了一样

留在原地更简单了  加一个自环呗

code

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
const int mod=2017;
ll n,j,k,t,y,x,anss,m,f[1001];
struct matrix
{
    ll a[101][101];
    matrix(){memset(a,0,sizeof(a));}
}a,ans;
matrix operator *(const matrix &x,const matrix &y)
{
    matrix z;int i,j,k;
    for(k=1;k<=n;k++)
    	for(i=1;i<=n;i++)
    		for(j=1;j<=n;j++)
    			z.a[i][j]=(z.a[i][j]+x.a[i][k]*y.a[k][j]%mod)%mod;
    return z;
}
int main() 
{
	int i;
    scanf("%d%d",&n,&m);
    n++;
    for(i=1;i<=m;i++)
    {	
		scanf("%d%d",&x,&y);
		a.a[x][y]=1;
		a.a[y][x]=1;
	}
    for(i=1;i<=n;i++)
	{
		a.a[i][n]=1;
		a.a[i][i]=1;
	}	
    for(i=1;i<=n;i++)ans.a[i][i]=1;
    scanf("%d",&k);
    do
    {
        if(k&1)ans=ans*a;
        a=a*a;k>>=1;
    }while(k);
    for(i=1;i<=n;i++)
		anss=(anss+ans.a[1][i])%mod;
    printf("%d\n",anss);
    return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值