漫步校园
LL最近沉迷于AC不能自拔,每天寝室、机房两点一线。由于长时间坐在电脑边,缺乏运动。他决定充分利用每次从寝室到机房的时间,在校园里散散步。整个HDU校园呈方形布局,可划分为n*n个小方格,代表各个区域。例如LL居住的18号宿舍位于校园的西北角,即方格(1,1)代表的地方,而机房所在的第三实验楼处于东南端的(n,n)。因有多条路线可以选择,LL希望每次的散步路线都不一样。另外,他考虑从A区域到B区域仅当存在一条从B到机房的路线比任何一条从A到机房的路线更近(否则可能永远都到不了机房了…)。现在他想知道的是,所有满足要求的路线一共有多少条。你能告诉他吗?
Input每组测试数据的第一行为n(2=<n<=50),接下来的n行每行有n个数,代表经过每个区域所花的时间t(0<t<=50)(由于寝室与机房均在三楼,故起点与终点也得费时)。
Output针对每组测试数据,输出总的路线数(小于2^63)。
Sample Input
3
1 2 3
1 2 3
1 2 3
3
1 1 1
1 1 1
1 1 1
Sample Output
1
6
//本周练DP,这题竟然是用优先队列的bfs,先求出终点到所有点的最短路,然后dfs找出所有可能的种数,dfs的时候用了dp思想吧
注意理解,他只会走能缩短最短路的点
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 #include <queue> 5 using namespace std; 6 #define LL long long 7 #define MX 55 8 const int INF = 1e8; 9 struct Node 10 { 11 int x,y; 12 int s; //耗时 13 bool operator <(const Node& b)const 14 { 15 return s>b.s; 16 } 17 }; 18 int n; 19 int mp[MX][MX]; 20 int dis[MX][MX]; 21 int vis[MX][MX]; 22 LL res[MX][MX]; //答案 23 int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}}; 24 25 void bfs() 26 { 27 memset(vis,0,sizeof(vis)); 28 for (int i=1;i<=n;i++) 29 for (int j=1;j<=n;j++) 30 dis[i][j]=INF; 31 priority_queue<Node> Q; 32 vis[n][n]=1; 33 dis[n][n]=mp[n][n]; 34 Node now = (Node){n,n,mp[n][n]}; 35 Q.push(now); 36 while (!Q.empty()) 37 { 38 now = Q.top();Q.pop(); 39 Node nex; 40 for (int i=0;i<4;i++) 41 { 42 nex.x = now.x+dir[i][0]; 43 nex.y = now.y+dir[i][1]; 44 if (nex.x>=1&&nex.x<=n&&nex.y>=1&&nex.y<=n&&!vis[nex.x][nex.y]) 45 { 46 nex.s = now.s+mp[nex.x][nex.y]; 47 vis[nex.x][nex.y]=1; 48 dis[nex.x][nex.y]=nex.s; 49 Q.push(nex); 50 } 51 } 52 } 53 } 54 55 LL dfs(int x,int y) 56 { 57 if (x==n&&y==n) return 1; 58 if (res[x][y]!=-1) return res[x][y]; 59 res[x][y]=0; 60 int nx,ny; 61 for (int i=0;i<4;i++) 62 { 63 nx = x+dir[i][0]; 64 ny = y+dir[i][1]; 65 if (nx>=1&&nx<=n&&ny>=1&&ny<=n&&dis[nx][ny]<dis[x][y]) 66 res[x][y]+=dfs(nx,ny); 67 } 68 return res[x][y]; 69 } 70 71 int main() 72 { 73 while (scanf("%d",&n)!=EOF) 74 { 75 for (int i=1;i<=n;i++) 76 for (int j=1;j<=n;j++) 77 scanf("%d",&mp[i][j]); 78 bfs(); 79 memset(res,-1,sizeof(res)); 80 dfs(1,1);//搜路径个数 81 printf("%I64d ",res[1][1]); 82 } 83 return 0; 84 }