BZOJ1875 HH去散步
这题 我承认 我过于NAIVE了 我把不能走回边 搞成了 走到一个点必须休息一下。。。
发现它的边数非常少 所以 按边建立矩阵 就可以十分科学的完成本题
矩乘我一定要封装进p,q
BZOJ 1875
1 #include<bits/stdc++.h> 2 #define mod 45989 3 #define ll long long 4 #define breaks printf("!\n"); 5 using namespace std; 6 7 inline int read() 8 { 9 int x=0,f=1;char ch=getchar(); 10 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 11 while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} 12 return x*f; 13 } 14 struct edge 15 { 16 int u,v,next; 17 }vs[300]; 18 int st[80],ee=1; 19 int n,m,t,A,B; 20 struct matrix 21 { 22 int mat[130][130]; 23 void clr() 24 { 25 for(int i=1;i<=ee;i++) 26 for(int j=1;j<=ee;j++) 27 mat[i][j]=0; 28 } 29 }M; 30 matrix operator*(matrix a,matrix b) 31 { 32 matrix tmp; tmp.clr(); 33 for(int i=1;i<=ee;i++) 34 for(int j=1;j<=ee;j++) 35 for(int k=1;k<=ee;k++) 36 (tmp.mat[i][j]+=1ll*a.mat[i][k]*b.mat[k][j]%mod)%=mod; 37 return tmp; 38 } 39 matrix operator^(matrix x,int p) 40 { 41 matrix tmp;tmp.clr(); 42 for(int i=1;i<=ee;i++) 43 tmp.mat[i][i]=1; 44 for(;p;p>>=1,x=x*x) 45 if(p&1)tmp=tmp*x; 46 return tmp; 47 } 48 inline void addedge(int u,int v) 49 { 50 vs[++ee].v=v;vs[ee].u=u; 51 vs[ee].next=st[u];st[u]=ee; 52 } 53 int main() 54 { 55 // freopen("a.out","w",stdout); 56 n=read();m=read();t=read(); 57 A=read();B=read(); 58 for(int i=1;i<=m;i++) 59 { 60 int a=read(),b=read(); 61 addedge(a,b);addedge(b,a); 62 } 63 matrix xx; xx.clr(); 64 for(int i=st[A];i;i=vs[i].next) 65 xx.mat[1][i]++; 66 for(int i=2;i<=ee;i++) 67 for(int j=2;j<=ee;j++) 68 if(vs[i].v==vs[j].u) 69 if(i!=(j^1))M.mat[i][j]++; 70 // xx.print(); M.print(); 71 xx=xx*(M^(t-1)); int ans=0; 72 for(int i=st[B];i;i=vs[i].next) 73 (ans+=xx.mat[1][i^1])%=mod; 74 cout<<ans<<endl; 75 return 0; 76 }