标签:为我 turn 算法 end bool 所有路径 const jks 目的
这里需要读懂题意中的一句话“另外,他考虑从A区域到B区域仅当存在一条从B到机房的路线比任何一条从A到机房的路线更近(否则可能永远都到不了机房了…)。”
这句话的意思是从(1, 1)
到(n, n)
的所有路径中,只选择距离最短的路径,并输出最短路径的条数。就是我们找出最短距离后,看看有多少条路到达目的地是最短距离。
从题意我们也就知道了,我们需要找出每个点到目的地的最短路是多少。这里我们最先想到的就是一些最短路的算法了,比如Dijkstra
算法,需要注意的是这里的图形是一个矩阵,而不是普通的那种图,所以这里的最短路算法和常见的最短路算法有些不同,这里的bfs
函数其实也是使用的这个最短路算法的思想,也是找出一个点来进行松弛。
还有需要注意点的是我们要倒过来进行最短路的计算,计算从(n, n)
到其他各个点的最短路径。为什么要这样呢?因为我们的算法是单源最短路,我们需要知道所有的点到终点的最短路,如果是从(1, 1)
开始计算,我们得到的是从(1,1)
到各个点的最短路经,思路反过来就能解决,真神奇!
接下来我们就要计算出有多少条路了,如果没有要求的话,最容易想到的是可以使用dfs
来计算出路径的种类,这里我也是这样做的,但是这个题有条件,每一步只能最近的路,上面我们已经知道了每个点到终点的最短距离了,我们使用dfs
进行拓展的时候可以判断我们要走的下一个点是不是最优的那个点(注意,可能下一步的最优点可能由多个),其实就是多了个条件判断,很有意思。
下们就是实现的代码。
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<sstream>
typedef long long ll;
using namespace std;
const double esp=1e-6;
const int inf=0x3f3f3f3f;
const int MAXN=50+7;
struct node{
int x, y;
node(){}
node(int a, int b){
x = a;
y = b;
}
};
int gox[4] = {-1, 1, 0, 0}; //上下左右
int goy[4] = {0, 0, -1, 1};
int mp[MAXN][MAXN], dis[MAXN][MAXN];
ll road[MAXN][MAXN];
bool vis[MAXN][MAXN];
int n;
void bfs(){//找点(n, n)到其他点的最短距离
vis[n][n] = 1;
dis[n][n] = mp[n][n];
queue<node> que;
que.push(node(n, n));
while(!que.empty())
{
node cur = que.front();
que.pop();
vis[cur.x][cur.y] = 0;
for(int i=0; i<4; i++)
{
node nt(cur.x + gox[i], cur.y + goy[i]);
if(nt.x < 1 || nt.x > n || nt.y < 1 || nt.y > n)
continue;
if(dis[nt.x][nt.y] > dis[cur.x][cur.y] + mp[nt.x][nt.y]){
dis[nt.x][nt.y] = mp[nt.x][nt.y] + dis[cur.x][cur.y];
if(!vis[nt.x][nt.y]){
vis[nt.x][nt.y] = 1;
que.push(node(nt.x, nt.y));
}
}
}
}
}
ll dfs(int x, int y)
{
if(x == n && y == n)
return 1;
if(road[x][y] != -1)
return road[x][y];
road[x][y] = 0;
int ntx, nty;
for(int i=0; i<4; i++)
{
ntx = x + gox[i];
nty = y + goy[i];
if(ntx < 1 || ntx > n || nty < 1 || nty > n || dis[ntx][nty] >= dis[x][y])
continue;
road[x][y] += dfs(ntx, nty);
}
return road[x][y];
}
int main()
{
while(cin>>n)
{
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++){
cin>>mp[i][j];
road[i][j] = -1;
dis[i][j] = inf;
vis[i][j] = 0;
}
bfs();
cout<<dfs(1, 1)<<endl;
}
return 0;
}
标签:为我 turn 算法 end bool 所有路径 const jks 目的
原文地址:https://www.cnblogs.com/alking1001/p/12559256.html