Processing math: 100%

洛谷 P4159 [SCOI2009]迷路

windy在有向图中迷路了。 该有向图有 N 个节点,windy从节点 0 出发,他必须恰好在 T 时刻到达节点 N-1。 现在给出该有向图,你能告诉windy总共有多少种不同的路径吗? 注意:windy不能在某个节点逗留,且通过某有向边的时间严格为给定的时间。

根据题意,可以写出转移方程

fi,j=fr,jw[r]

fi,j表示第j时刻在第i个点时的方案数,ri的前驱,w[r]为距离

T109,所以肯定是不可行的,就要用到矩阵加速

如果对于上面那个转移方程是无法矩阵加速的

但是边权只有19,我们可以把j分开表示,也就是把所有距离的情况都表示出来

那么对于上面的那个转移方程就有两种转移形式

  • 这个距离j不是真正的距离,那么fr,j可以从fr,j1继承

  • 这个j是真正的距离,那么fr,jfi,j是有贡献的

代码和拆点一样= =

Code

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int n,t,d[500][500],s[500][500],b[500][500],p=2009;
char ch;
void jzc(int x[500][500],int y[500][500])
{
	for (int i=1;i<=n*9;i++)
		for (int j=1;j<=n*9;j++)
			for (int k=1;k<=n*9;k++)
				b[i][j]=(b[i][j]+x[i][k]*y[k][j]%p)%p;
	for (int i=1;i<=n*9;i++)
		for (int j=1;j<=n*9;j++)
			x[i][j]=b[i][j],b[i][j]=0;
}
int main()
{
	cin>>n>>t;
	for (int i=1;i<=n;i++)
	{
		for (int j=1;j<=8;j++)     //第一个的继承关系
			d[i+j*n][i+(j-1)*n]=1;
		for (int j=1;j<=n;j++)
		{
			cin>>ch;
			d[i][j+n*((ch-'0')-1)]=1;   //真正的边
		}
	}
	for (int i=1;i<=n*9;i++)
		s[i][i]=1;
	while (t)
	{
		if (t&1)jzc(s,d);
		jzc(d,d);
		t>>=1;
	}
	cout<<s[1][n]<<endl;
	return 0;
}
posted @   eee_hoho  阅读(196)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示