标签:pop read scan ext nbsp fine 迪杰斯特拉 code UI
似乎弗洛伊德和迪杰斯特拉都干不了统计方案数,spfa的话就是不断入队就好。
#include <cstdio> #include <cstring> #include <queue> #define get_hash(a,b) (a-1)*m+b const int N=55; const int Inf=0x3f3f3f3f; int t1[8]={-1,-2,-2,-1,1,2,2,1},t2[8]={-2,-1,1,2,2,1,-1,-2}; int f[N*N],dis[N*N],n,s[N][N],m,hash[N][N],S,E,all; bool in[N*N],v[N][N],is[N*N],edge[N*N][N*N]; inline bool ok(int x,int y){ return x>0&&x<=n&&y>0&&y<=m&&s[x][y]!=2; } struct V{ int to,next; }c[N*N*N*N]; int head[N*N],t; std::queue<int>q; inline void add(int x,int y){ c[++t].to=y,c[t].next=head[x],head[x]=t; } void dfs(int x,int y){ if(v[x][y])return; v[x][y]=1; for(int i=0,p1,p2;i<8;i++){ p1=x+t1[i],p2=y+t2[i]; if(ok(p1,p2)==false)continue; if(s[p1][p2]==1)dfs(p1,p2); else is[hash[p1][p2]]=true; } } void read_build(){ scanf("%d%d",&n,&m),all=n*m; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){ scanf("%d",&s[i][j]),hash[i][j]=get_hash(i,j); if(s[i][j]==3)S=hash[i][j]; if(s[i][j]==4)E=hash[i][j]; } for(int i=1,p1,p2;i<=n;i++) for(int j=1;j<=m;j++) if(s[i][j]!=2&&s[i][j]!=4) if(s[i][j]==1){ memset(is,0,sizeof(is)),dfs(i,j); for(int x=1;x<=all;x++) if(is[x]&&x!=E) for(int y=1;y<=all;y++) if(x!=y&&is[y]) edge[x][y]=true; } else for(int k=0;k<8;k++){ p1=t1[k]+i,p2=t2[k]+j; if(ok(p1,p2)&&s[p1][p2]!=1) add(hash[i][j],hash[p1][p2]); } for(int i=1;i<=all;i++) for(int j=1;j<=all;j++) if(i!=j&&edge[i][j]) add(i,j); } void spfa_print(){ q.push(S),memset(dis,0x3f,sizeof(dis)),dis[S]=0,f[S]=1,in[S]=true; while(!q.empty()){ int x=q.front();q.pop(),in[x]=false; for(int i=head[x];i;i=c[i].next) if(dis[x]+1<dis[c[i].to]){ dis[c[i].to]=dis[x]+1,f[c[i].to]=f[x]; if(in[c[i].to]==false)q.push(c[i].to),in[c[i].to]=true; } else if(dis[x]+1==dis[c[i].to]){ f[c[i].to]+=f[x]; if(in[c[i].to]==false)q.push(c[i].to),in[c[i].to]=true; } } if(f[E]==0)printf("-1"); else printf("%d\n%d",dis[E]-1,f[E]); } int main(){ read_build(),spfa_print(); return 0; }
标签:pop read scan ext nbsp fine 迪杰斯特拉 code UI
原文地址:http://www.cnblogs.com/TSHugh/p/7617799.html