Brief Description:
Given a non-circular graph that may have a heavy edge but no self-loop, the number of scenarios in which the number of steps between a and B two points is required is calculated. Answer modulus 45989.
(You can pass through a point several times, but you cannot immediately go back along the same edge.) )
(.. N <=, M <=, T <= 2^30. )
Analyse:
Because "does not go back along the same edge", the state of the K-step from point A is only relevant to the edge of the last step and its direction.
If each non-tangential edge is split into two pairs with a forward edge, then only the edge is concerned.
With i== (j^1), exclude immediately go back to the side.
For example: 2 0010 (U1->V1) 4 0100 (U2->V2)
3 0011 (V1->U1) 5 0101 (V2->U2)
----> (2&1) ==3 (3&1) ==2----> (4&1) ==5 (5&1) ==4
Friend Chain: http://www.shuizilong.com/house/archives/sdoi-2009-hh%E5%8E%BB%E6%95%A3%E6%AD%A5/
CODE:
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include < algorithm> #include <vector> #include <string> #include <queue> #include <deque> #include <stack> #include <map> #include <set> #define INF 0x7fffffff#define SUP 0x80000000#define _p 45989# Define MEM (A, B) memset (A,b,sizeof (a)) using namespace Std;typedef long long ll;const int n=100007;struct edge{ adjacency table node int to,next;} E[133];int head[55];int tot=2;void add_ (int u,int v) {e[tot].to=v; E[tot].next=head[u]; head[u]=tot++;} struct matrix{int mat[133][133]; Matrix () {mem (mat,0); } Friend Matrix operator * (Matrix A,matrix B)//non-member function overloads {matrix ans; for (int i=1;i<=tot;i++) {for (int. j=1;j<=tot;j++) {for (int k=1;k<=to t;k++) ans.mat[i][j]+=a.mat[i][k]*b.mat[k][j]%_p,ans.mat[i][j]%=_p; }} return ans; } Friend Matrix operator^ (Matrix A,int b) {matrix ans; for (int i=1;i<=tot;i++) ans.mat[i][i]=1; while (b) {if (b&1) ans=ans*a; Go back to the side a=a*a; b>>=1; } return ans; }};int Main () {int n,m,t,a,b; while (scanf ("%d%d%d%d%d", &n,&m,&t,&a,&b) ==5) {mem (head,-1); int u,v; for (int i=1;i<=m;i++) {scanf ("%d%d", &u,&v); Add_ (U,V); Add_ (V,u); } Matrix St,tt; for (int i=head[a];i!=-1;i=e[i].next) st.mat[1][i]=1; The initial step vector<int> en; for (int i=2;i<tot;i++)//Transfer matrix {int to=e[i].to; if (to==b) en.push_back (i); for (int j=head[to];j!=-1;j=e[j].next) {if (i== (j^1)) continue; Tt.mat[i][j]=1; }} int ans=0; st=st* (tt^ (t-1)); 1+ (t-1) ==t step , that is, the initial step + transfer t-1 times for (int i=0;i<en.size (); i++) {ans= (Ans+st.mat[1][en[i]])%_p; } printf ("%d\n", ans); } return 0;}
baoj1875 hh go for a Walk "matrix Shift"