以下是baidu找的题解
以单词为点,能前后相连的单词之间连边,得到一个有向图,求长度为奇数且小于等于N的不同的S->T的路径数。设邻接矩阵为A,则可通过求A
+ A ^ 3 + ... + A ^ N求解。构造一个矩阵后可通过logN次矩阵乘求解。
以下是本人代码
以单词为点,能前后相连的单词之间连边,得到一个有向图,求长度为奇数且小于等于N的不同的S->T的路径数。设邻接矩阵为A,则可通过求A
+ A ^ 3 + ... + A ^ N求解。构造一个矩阵后可通过logN次矩阵乘求解。
以下是本人代码
2 | 饕饕不绝 | 31MS | 0K | 2438B | C++ | 2008-10-22 12:53:26 |
- /*
- 求和的时候稍微做了点优化
- */
- #include <iostream>
- #include <string>
- using namespace std;
- #define MAX_SIZE 30
- char w[MAX_SIZE][11],ttmp[11];
- int moudle,k,size;
- inline int fid(char* k){int i;for(i=0;i<size;i++)if(strcmp(k,w[i])==0)return i;return 0;}
- long long tmp;
- struct Mat
- {
- short g[MAX_SIZE][2*MAX_SIZE];
- Mat operator+(const Mat&a)
- {
- Mat temp;
- int i,j;
- for(i=0;i<size;i++)
- for(j=0;j<size;j++)
- temp.g[i][j]=(g[i][j]+a.g[i][j])%moudle;
- return temp;
- }
- Mat operator*(const Mat&a)
- {
- int i,j,k;
- Mat temp;
- for(i=0;i<size;i++)
- for(j=0;j<size;j++)
- {
- tmp=0;
- for(k=0;k<size;k++)tmp+=g[i][k]*a.g[k][j];
- if(tmp>=moudle)tmp%=moudle;
- temp.g[i][j]=tmp;
- }
- for(i=0;i<size;i++)
- for(j=size;j<2*size;j++)
- {
- tmp=a.g[i][j];
- for(k=0;k<size;k++)tmp+=a.g[i][k]*g[k][j];
- if(tmp>=moudle)tmp%=moudle;
- temp.g[i][j]=tmp;
- }
- return temp;
- }
- }A,Ans,TA;
- Mat mul(Mat a,Mat b)
- {
- Mat ret;
- int i,j,k;
- for(i=0;i<size;i++)
- for(j=0;j<size;j++)
- {
- for(k=tmp=0;k<size;k++)tmp+=a.g[i][k]*b.g[k][j];
- if(tmp>=moudle)
- tmp%=moudle;
- ret.g[i][j]=tmp;
- ret.g[i][j+size]=a.g[i][j+size];
- }
- return ret;
- }
- inline Mat pow(Mat t, int k) {
- Mat temp;
- for(;k;k>>=1,t=t*t)
- if(k&0x1){temp=t;break;}
- for(k>>=1,t=t*t;k;k>>=1,t=t*t)
- if(k&0x1)temp=temp*t;
- return temp;
- }
- int main()
- {
- int i,j,t,sid,eid;
- moudle=10001;
- scanf("%d",&t);
- while(t--){
- scanf("%d",&size);
- for(i=0;i<size;i++)scanf("%s",w[i]);
- scanf("%s",ttmp);sid=fid(ttmp);
- scanf("%s",ttmp);eid=fid(ttmp);
- scanf("%d",&k);
- for(i=0;i<size;i++)for(j=0;j<size;j++)A.g[i][j]=(w[i][strlen(w[i])-1]==w[j][0]);
- TA=A;
- for(i=0;i<size;i++)for(j=size;j<2*size;j++)A.g[i][j]=(i==j-size);
- A=mul(A,A);
- Ans=pow(A,1+((k-2+(k&0x1))>>1));
- for(i=0;i<size;i++)
- for(j=0;j<size;j++)
- Ans.g[i][j]=Ans.g[i][j+size];
- Ans=mul(TA,Ans);
- printf("%d/n",Ans.g[sid][eid]);
- }
- return 0;
- }