【最短路】Maze

版权声明:本篇随笔版权归作者Etta(http://www.cnblogs.com/Etta/)所有,转载请保留原地址!

问题描述:

  小鼠a与小鼠b身处一个m×n的迷宫中,如图所示。每一个方格表示迷宫中的一个房间。这m×n个房间中有一些房间是封闭的,不允许任何人进入。在迷宫中任何位置均可沿上,下,左,右4个方向进入未封闭的房间。小鼠a位于迷宫的(p,q)方格中,它必须找出一条通向小鼠b所在的(r,s)方格的路。请帮助小鼠a找出所有通向小鼠b的最短道路。

 

编程任务:

  对于给定的小鼠的迷宫,编程计算小鼠a通向小鼠b的所有最短道路。

 

数据输入:

  由文件input.txt给出输入数据。第一行有3个正整数n,m,k,分别表示迷宫的行数,列数和封闭的房间数。接下来的k行中,每行2个正整数,表示被封闭的房间所在的行号和列号。最后的2行,每行也有2个正整数,分别表示小鼠a所处的方格(p,q)和小鼠b所处的方格(r,s)。

 

结果输出:

  将计算出的小鼠a通向小鼠b的最短路长度和有多少条不同的最短路输出到文件output.txt。文件的第一行是最短路长度。文件的第2行是不同的最短路数。

如果小鼠a无法通向小鼠b则输出“No Solution!”。

 

Input:

8 8 3

3 3

4 5

6 6

2 1

7 7

Output:

11

96

 

一、分析问题

       看到这道题想起搜索里经典的走迷宫求路径,于是直接bfs求最短路dfs搜路径数,奈何一个点始终TLE。于是有另一个快且简洁的方法。把每一个格子抽象为一个点,相邻的点之间有长度为1的边,SPFA求最短路径,递推求最短路径数。

 

二、解决问题

       SPFA+递推

Tips:

1.递推是难点

if(dis[u]>dis[v]+1)f[u]=f[v];

else if(dis[u]==dis[v]+1)f[u]+=f[v];//

2.使用一维数组代替二维数组使得队列实现更加方便

       F[i,j]=>f[i*(m-1)+j]

3.m*n的表格,m行n列//

 

三、代码实现

 1 #include<cstdio>
 2 #include<queue>
 3 using namespace std;
 4 
 5 const int MA=100,inf=4e8;
 6 int m,n,k,st,en;
 7 int x,y,t,a,b,c,d;
 8 int dis[MA*MA],fa[MA*MA],ex[MA*MA];
 9 queue<int>p;
10 
11 int calc(int x,int y)
12 {
13     return (x-1)*m+y;
14 }
15 
16 void spfa(int u,int v)
17 {
18     if(dis[u]>dis[v]+1)
19     {
20         fa[u]=fa[v];
21         dis[u]=dis[v]+1;
22         if(!ex[u])
23         {
24             p.push(u);
25             ex[u]=1;
26         }
27     }
28     else
29     if(dis[u]==dis[v]+1)
30     fa[u]+=fa[v];
31 }
32 
33 void SPFA()
34 {
35     p.push(st);
36     dis[st]=0;
37     fa[st]=1;
38     while(!p.empty())
39     {
40         int tmp=p.front();
41         ex[tmp]=0;
42         p.pop();
43         if(tmp+m<=n*m&&dis[tmp+m]!=-1)spfa(tmp+m,tmp);
44         if(tmp-m>=0&&dis[tmp-m]!=-1)spfa(tmp-m,tmp);
45         if(tmp%m!=0&&dis[tmp+1]!=-1)spfa(tmp+1,tmp);
46         if(tmp%m!=1&&dis[tmp-1]!=-1)spfa(tmp-1,tmp);
47     }
48 }
49 
50 int main()
51 {
52     scanf("%d%d%d",&n,&m,&k);
53     for(int i=1;i<=n*m;++i)dis[i]=inf;
54     for(int i=1;i<=k;++i)
55     {
56         scanf("%d%d",&x,&y);
57         t=calc(x,y);
58         dis[t]=-1;
59     }
60     scanf("%d%d%d%d",&a,&b,&c,&d);
61     st=calc(a,b);
62     en=calc(c,d);
63     
64     SPFA();
65     
66     if(dis[en]==inf)printf("No Solution!\n");
67     else printf("%d\n%d\n",dis[en],fa[en]);
68     return 0;
69 }

 

posted @ 2017-01-28 12:46  Etta19  阅读(241)  评论(0编辑  收藏  举报