#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
struct node{
int x,y,cost;
friend bool operator < (node a,node b){
return a.cost > b.cost;
}
};
int n;
int graph[55][55];
bool vis[55][55];
long long dp[55][55];
int dist[55][55];
int dx[] = {0,0,1,-1};
int dy[] = {1,-1,0,0};
void bfs(){
priority_queue<node> q;
memset(vis,false,sizeof(vis));
node cur,next;
cur.x = n;
cur.y = n;
cur.cost = graph[n][n];
q.push(cur);
while(!q.empty()){
cur = q.top(); //当前距离最小的一个点
q.pop();
if(vis[cur.x][cur.y]) continue; //只有第一次出队的点才是最小值的点
vis[cur.x][cur.y] = true;
dist[cur.x][cur.y] = cur.cost;
for(int i=0;i<4;i++){
next.x = cur.x+dx[i];
next.y = cur.y+dy[i];
if(next.x>=1 && next.x<=n && next.y>=1 && next.y<=n && !vis[next.x][next.y]){
next.cost = cur.cost+graph[next.x][next.y];
q.push(next);
}
}
}
}
long long dfs(int x,int y){
if(dp[x][y]!=-1) return dp[x][y];
dp[x][y] = 0;
for(int i=0;i<4;i++){
int xx = x+dx[i];
int yy = y+dy[i];
if(xx>=1 && xx<=n && yy>=1 && yy<=n){
if(dist[xx][yy] < dist[x][y]) //约束条件
dp[x][y] += dfs(xx,yy);
}
}
return dp[x][y];
}
int main(){
while(scanf("%d",&n)!=EOF){
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",&graph[i][j]);
bfs(); //先用bfs计算距离,由于每个点的cost不是1,所以需要使用优先队列
memset(dp,-1,sizeof(dp));
dp[n][n] = 1;
printf("%lld\n",dfs(1,1)); //得到距离之后,使用dfs的记忆化搜索,得到解的个数
//在生成解的时候,需要设定约束条件
}
return 0;
}
HDU 1428 bfs(优先队列计算最短距离) dfs(记忆化搜索)
猜你喜欢
转载自blog.csdn.net/weixin_42246923/article/details/80760695
今日推荐
周排行