[SCOI2009]迷路
Time Limit:10000MS Memory Limit:165536K
Total Submit:40 Accepted:24
Case Time Limit:1000MS
Description
windy在有向图中迷路了。
该有向图有 N 个节点,windy从节点 0 出发,他必须恰好在 T 时刻到达节点 N-1。
现在给出该有向图,你能告诉windy总共有多少种不同的路径吗?
注意:windy不能在某个节点逗留,且通过某有向边的时间严格为给定的时间。
Input
第一行包含两个整数,N T。
接下来有 N 行,每行一个长度为 N 的字符串。
第i行第j列为’0’表示从节点i到节点j没有边。
为’1’到’9’表示从节点i到节点j需要耗费的时间。
Output
包含一个整数,可能的路径数,这个数可能很大,只需输出这个数除以2009的余数。
Sample Input
【输入样例一】
2 2
11
00
【输入样例二】
5 30
12045
07105
47805
12024
12345
Sample Output
【输出样例一】
1
【样例解释一】
0->0->1
【输出样例二】
852
Hint
30%的数据,满足 2 <= N <= 5 ; 1 <= T <= 30 。
100%的数据,满足 2 <= N <= 10 ; 1 <= T <= 1000000000 。
Source
Day2
我擦啊!61.187.179.132:8080/JudgeOnline/showproblem
我一开始没想出来怎么做,很明显要用矩阵乘法,所以我就想怎么搞。。
我想了半天没有什么头绪,感觉这个长度很麻烦,感觉矩阵乘法就是从一个推出下一个,推不出下面很多个额。。很头疼。
过了一天发现由于长度最长是9。。。所以把每9个打包起来就再递推就OK了。。
可是我:
晕死了。。那几个WA是我故意写return 0查出错点的。。
最后发现原来因为矩阵有点大,导致如果我直接在乘法里写临时变量的话会MLE。。
靠靠靠。。我本来就没什么AC率的。。现在悲剧大发了。。
Code:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
#include<cstring>
#define rep(i,n) for(int i=0;i<n;i++)
#define pb push_back
using namespace std;
const int maxt=9,maxv=90,maxn=10,mod=2009;
int n,v;
inline int node(int time,int pos)
{
return time*n+pos;
}
int tmp[maxv][maxv];
struct Mat
{
int M[maxv][maxv];
int&operator()(int i,int j){return M[i][j];}
Mat(){memset(M,0,sizeof(M));}
void operator*=(Mat&o)
{
memset(tmp,0,sizeof(tmp));
rep(i,v)rep(j,v)rep(k,v)
tmp[i][j]+=M[i][k]*o(k,j),tmp[i][j]%=mod;
memcpy(M,tmp,sizeof(M));
}
void operator=(const Mat&o)
{
memcpy(M,o.M,sizeof(M));
}
}orig;
int Map[maxn][maxn];
void Power(int n,Mat&ret)
{
if(n==1){ret=orig;return;}
Power(n/2,ret);
ret*=ret;
if(n&1)ret*=orig;
}
int main()
{
//freopen("in","r",stdin);
//freopen("road.in","r",stdin);
//freopen("road.out","w",stdout);
int T;
scanf("%d %d",&n,&T);char x;v=n*9;
rep(i,n)
{
scanf("n");
rep(j,n)scanf("%c",&x),Map[i][j]=x-‘0’;
}
rep(i,n)for(int t=0;t<8;t++)
orig(node(t,i),node(t+1,i))++;
rep(i,n)rep(j,n)if(Map[j][i])
orig(node(8,i),node(9-Map[j][i],j))++;
Mat Ans;Power(T,Ans);
int dp[maxn][maxt]={0};
dp[0][0]=1;
for(int t=1;t<maxt;t++)
{
rep(i,n)rep(j,n)
if(Map[j][i])
if(t-Map[j][i]>=0)
{
dp[i][t]+=dp[j][t-Map[j][i]];
dp[i][t]%=mod;
}
}
int ans=0;
rep(i,n)rep(t,maxt)
{
ans+=Ans(node(0,n-1),node(t,i))*dp[i][t];
ans%=mod;
}
cout<<ans<<endl;
}

