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 }
View Code

 

posted @ 2017-01-23 20:37  蛤鸡  阅读(250)  评论(0编辑  收藏  举报