题目大意:给你一个n*m的网格图,求哈密顿回路数
插头DP板子题,搞了一天终于过了
1 #include <cmath> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #define N1 20 6 #define M1 50010 7 #define ll long long 8 #define uint unsigned int 9 #define il inline 10 #define jr 50000 11 using namespace std; 12 13 int n,m,now,pst,ex,ey; 14 int mp[N1][N1]; 15 char str[N1]; 16 ll ans=0; 17 struct Hash{ 18 int head[M1],nxt[M1],to[M1],cte; 19 ll val[M1]; 20 void ae(int u,int v,int w){ 21 cte++;to[cte]=v,val[cte]=w; 22 nxt[cte]=head[u],head[u]=cte;} 23 void clr(){ 24 memset(head,0,sizeof(head)); 25 cte=0;} 26 int find(int w){ 27 int x=w%jr; 28 for(int j=head[x];j;j=nxt[j]){ 29 int v=to[j]; 30 if(v==w) return j; 31 }return 0;} 32 void update(int x,ll w){ 33 int i=find(x); 34 if(!i) ae(x%jr,x,0),i=cte; 35 val[i]+=w;} 36 }h[2]; 37 void solve(int x,int y,int type) 38 { 39 int s,a,b,c,res; 40 h[now].clr(); 41 for(int k=0;k<jr;k++) 42 for(int j=h[pst].head[k];j;j=h[pst].nxt[j]) 43 { 44 s=h[pst].to[j]; 45 a=(s>>(y*2))&3; 46 b=(s>>((y+1)*2))&3; 47 if(!mp[x][y]){ 48 if(!a&&!b) h[now].update(s,h[pst].val[j]); 49 }else if(!a&&!b){ 50 if(mp[x][y+1]&&mp[x+1][y]) h[now].update(s^(1<<(y*2))^(2<<((y+1)*2)),h[pst].val[j]); 51 }else if(a&&!b){ 52 if(mp[x][y+1]) h[now].update(s^(a<<(y*2))^(a<<((y+1)*2)),h[pst].val[j]); 53 if(mp[x+1][y]) h[now].update(s,h[pst].val[j]); 54 }else if(!a&&b){ 55 if(mp[x+1][y]) h[now].update(s^(b<<((y+1)*2))^(b<<(y*2)),h[pst].val[j]); 56 if(mp[x][y+1]) h[now].update(s,h[pst].val[j]); 57 }else if(a==2&&b==1){ 58 h[now].update(s^(2<<(y*2))^(1<<((y+1)*2)),h[pst].val[j]); 59 }else if(a==2&&b==2){ 60 res=1; 61 for(int i=y-1;i>=0;i--){ 62 c=(s>>(i*2))&3; 63 if(c==2) res++; 64 if(c==1) res--; 65 if(!res){ 66 h[now].update(s^(2<<(y*2))^(2<<((y+1)*2))^(3<<(i*2)),h[pst].val[j]); 67 break;} 68 } 69 }else if(a==1&&b==1){ 70 res=1; 71 for(int i=y+2;i<=m;i++){ 72 c=(s>>(i*2))&3; 73 if(c==1) res++; 74 if(c==2) res--; 75 if(!res){ 76 h[now].update(s^(1<<(y*2))^(1<<((y+1)*2))^(3<<(i*2)),h[pst].val[j]); 77 break;} 78 } 79 }else if(a==1&&b==2&&x==ex&&y==ey) 80 ans+=h[pst].val[j]; 81 } 82 } 83 void right_move() 84 { 85 h[now].clr(); 86 for(int k=0;k<jr;k++) 87 for(int j=h[pst].head[k];j;j=h[pst].nxt[j]) 88 { 89 int s=h[pst].to[j]; 90 if(!h[pst].val[j]) continue; 91 h[now].update(s<<2,h[pst].val[j]); 92 } 93 } 94 95 int main() 96 { 97 //freopen("t2.in","r",stdin); 98 scanf("%d%d",&n,&m); 99 for(int i=0;i<n;i++){ 100 scanf("%s",str); 101 for(int j=0;j<m;j++) 102 if(str[j]=='.') mp[i][j]=1,ex=i,ey=j; 103 } 104 now=1,pst=0; 105 h[pst].update(0,1); 106 for(int i=0;i<n;i++){ 107 for(int j=0;j<m;j++) 108 { 109 solve(i,j,mp[i][j]); 110 swap(now,pst); 111 } 112 right_move(); 113 swap(now,pst); 114 } 115 printf("%lld ",ans); 116 return 0; 117 }