/*
分析:
最短路+递推。
水题一道,估计有点儿困了,一直理解错题意&&犯低级错误。。。
预处理出每个点到终点的最短路,然后只要满足dis[next_x][next_y]<
dis[now_x][now_x],那么就将now的路线数推给next就行了。
2013-06-14
*/
#include"iostream" #include"cstdio" #include"queue" #include"cstring" using namespace std; const int N=55; const int inf=123456789; int n,map[N][N],dis[N][N]; __int64 dp[N][N]; int dir[4][2]={1,0, 0,1, -1,0, 0,-1}; struct node1 { int x,y,dis; bool friend operator<(node1 n1,node1 n2){ return n2.dis<n1.dis; } }; void bfs1() { int i,flag[N][N]; node1 now,next; priority_queue<node1>q; memset(flag,0,sizeof(flag)); now.x=n-1; now.y=n-1; now.dis=map[now.x][now.y]; q.push(now); while(!q.empty()) { now=q.top(); q.pop(); if(flag[now.x][now.y]) continue; flag[now.x][now.y]=1; for(i=0;i<4;i++) { next.x=now.x+dir[i][0]; next.y=now.y+dir[i][1]; if(next.x<0 || next.x>=n || next.y<0 || next.y>=n) continue; if(flag[next.x][next.y]) continue; if(dis[now.x][now.y]+map[next.x][next.y] >= dis[next.x][next.y]) continue; next.dis=dis[next.x][next.y]=dis[now.x][now.y]+map[next.x][next.y]; q.push(next); } } } struct node2 { int x,y,dis; bool friend operator<(node2 n1,node2 n2){ return n1.dis<n2.dis; } }; void bfs2() { int i,flag[N][N]; node2 now,next; priority_queue<node2>q; memset(flag,0,sizeof(flag)); now.x=0; now.y=0; now.dis=dis[0][0]; q.push(now); flag[0][0]=1; while(!q.empty()) { now=q.top(); q.pop(); for(i=0;i<4;i++) { next.x=now.x+dir[i][0]; next.y=now.y+dir[i][1]; if(next.x<0 || next.x>=n || next.y<0 || next.y>=n) continue; next.dis=dis[next.x][next.y]; if(next.dis < now.dis) { dp[next.x][next.y]+=dp[now.x][now.y]; if(!flag[next.x][next.y]) {q.push(next);flag[next.x][next.y]=1;} } } } } int main() { int i,l; while(scanf("%d",&n)!=-1) { for(i=0;i<n;i++) for(l=0;l<n;l++) { scanf("%d",&map[i][l]); dp[i][l]=0; dis[i][l]=inf; } dp[0][0]=1; dis[n-1][n-1]=map[n-1][n-1]; bfs1(); bfs2(); printf("%I64d\n",dp[n-1][n-1]); } return 0; }