第4题 路线统计(route.cpp/pas)
【问题描述】
给出一个n个点有向图,求从s点到f点恰好经过时间t的路径总数。不能在某个点停留,可以重复的走各点。
【输入数据】
第一行包含一个整数n, 所有点是从0到n-1编号.
接下来n行,每行包含n个字符. 第i行第j个字符表示i到j需要的时间,字符只可能是’1’到’5’, 或者是’.’表示i不能到达j, 保证主对角线都是’.’。
接下来一行3个整数s, f, t。
【输出数据】
输出总方案数mod 502630的值。
【样例输入】route.in
3
.12
2.1
12.
0 2 5
【样例输出】route.out
8
【数据范围及提示】
对于20%的数据, 输入的字符不是’1’就是’.’;
对于100%的数据, 1 <= n <= 10; 1 <= s,f <= n; 1 <= t <= 10^9
#include<cstdio> #include<cstring> #include<iostream> using namespace std; const int MOD=502630; struct matrix { int f[55][55]; void clear() { memset(f,0,sizeof(f)); } }st,ans,E; int n; char s[15]; void readdata() { st.clear(); scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%s",s); for(int j=1;j<=n;j++) { if(s[j-1]!='.') { int ret=s[j-1]-'0'; for(int k=1;k<ret;k++) { st.f[(k-1)*n+i][k*n+i]=1; } st.f[(ret-1)*n+i][j]=1; } } } n*=5; E.clear(); for(int i=1;i<=n;i++)E.f[i][i]=1; } matrix o_o(matrix a,matrix b) { matrix c; c.clear(); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) for(int k=1;k<=n;k++) { c.f[i][j]=(c.f[i][j]+((long long)a.f[i][k]*b.f[k][j])%MOD)%MOD; } return c; } matrix mult(matrix a,int t) { matrix c=E; while(t) { if(t%2)c=o_o(c,a); t>>=1; a=o_o(a,a); } return c; } void work() { int start,finish,t; scanf("%d%d%d",&start,&finish,&t); start++;finish++; matrix ans=mult(st,t); printf("%d\n",ans.f[start][finish]); } int main() { freopen("route.in","r",stdin); freopen("route.out","w",stdout); readdata(); work(); return 0; }
附glk's code.
#include<cstdio> #include<iostream> #include<cstring> using namespace std; const int mod = 502630; #define LL long long struct Mat{ int A[300][300]; int h,l; Mat() {memset(A,0,sizeof(A));h = l = 0;} Mat operator * (const Mat& B)const{ Mat C; C.h = h;C.l = B.l; for(int i = 1;i <= h;++i) for(int j = 1;j <= B.l;++j){ int tmp = 0; for(int k = 1;k <= l;++k) tmp = (tmp + ((LL)A[i][k] * B.A[k][j])%mod)%mod; C.A[i][j] = tmp; } return C; } }; char Can[15][15]; Mat Pow(Mat B,int n){ Mat ans = B; for(int i = 1;i <= B.h;++i) for(int j = 1;j <= B.l;++j) ans.A[i][j] = (i==j); while(n){ if(n&1) ans = ans * B; B = B * B; n>>=1; } return ans; } int main(){ freopen("route.in","r",stdin); freopen("route.out","w",stdout); //A*A为t=2,A^k means t = k + 1 //ans = A^(t-1)[s,f] int n,tot,s,f,t; scanf("%d",&n); for(int i = 1;i <= n;++i)scanf("%s",Can[i]+1); tot = n; scanf("%d%d%d",&s,&f,&t); ++s,++f; Mat B; #define CC B.A for(int i = 1;i <= n;++i){ for(int j = 1;j <= n;++j){ if(Can[i][j]=='.') continue; int tmp = Can[i][j]-'0'; for(int k = 1;k < tmp;++k) CC[(k-1)*n+i][k*n+i] = 1; CC[(tmp-1)*n+i][j] = 1; } } B.h = B.l = n * 5; Mat ans = Pow(B,t); printf("%d",ans.A[s][f]); return 0; }