题意:指定v1,v2,要求计算出在t1,t2天内从v1->v2的走法
思路:可以知道由矩阵求,即将其建图A,求矩阵A^t1 + ...... + A^t2. A^n后,/*A.xmap[v1][v2]即是从v1到v2要n步
所以先预处理出A^1 -A^10000的情况,后面再注意下细节,计算即可.
(每条道路走需要花一天的时间,且不能在某个城市停留,且t1=0时的走法数为0)
开始以为只要t1 = 0就输出0,结果不停WA,一直对照别人的代码- -
结果偶然发现这个特例,它喵的我也是醉了,才发现是题意理解错了,好惨...Orz
- 特例:
- Input:
- 1
- 1 1
- 1
- 1 1 0 1
- Ouput:
- 1
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<cmath> #include<algorithm> #include<string> #include<map> #include<set> #include<vector> #include<queue> #include<stack> #include<functional> using namespace std; typedef long long ll; const int mod=2008; const int maxn=5e5; map<int,int>has; struct Maxtri { int xmap[30][30]; }; int siz; Maxtri mat[10005]; Maxtri Mul(Maxtri &a,Maxtri &b) { Maxtri c; for(int i=0; i<siz; i++) { for(int j=0; j<siz; j++) { c.xmap[i][j]=0; for(int k=0; k<siz; k++) { c.xmap[i][j]+=a.xmap[i][k]*b.xmap[k][j]; c.xmap[i][j]%=mod; } } } return c; } int main() { int n,u,v,k; int v1,v2,t1,t2; while(scanf("%d",&n) != EOF) { siz = 0; memset(mat[0].xmap,0,sizeof(mat[0].xmap)); has.clear(); for(int i = 1; i <= n; i++) { scanf("%d%d",&u,&v); if(has.find(u)==has.end()) { has[u]=siz++; } if(has.find(v)==has.end()) { has[v]=siz++; } mat[0].xmap[has[u]][has[v]] ++; } for(int i=1; i<10001; i++) mat[i]=Mul(mat[i-1],mat[0]); scanf("%d",&k); while(k--) { scanf("%d%d%d%d",&v1,&v2,&t1,&t2); if(has.find(v1)==has.end()||has.find(v2)==has.end() || (!t1 && !t2)) { printf("0 "); continue; } if(t1 > t2) swap(t1,t2); int ans=0; for(int i=t1-1; i<t2; i++) { if(i == -1) continue; ans= (ans + mat[i].xmap[has[v1]][has[v2]])%mod; } printf("%d ",ans%mod); } } return 0; }