Description
⑨每天吃完晚饭后都会从家出发到雾之湖及其周围去散步下,最终到达魔法森林的入口,并且尽可能尝试不同的路径。雾之湖及其周围可以抽象为一个矩形,划分为n*m块区域,⑨家为(1,1),散步时⑨在某个区域会逗留一段时间,然后移动到东西南北相邻的其中一个格子(移动时间忽略不计),经过若干次移动最终到达魔法森林(n,m)。因为是散步,所以起点和终点⑨都会逗留一段时间。⑨表示虽然是闲逛,但是也不能太浪费时间,还是得去终点(n,m)的,所以只有至少存在一条从B到终点的时间比从A到终点的所有路径所花费的时间更少时才可以从A到B。现在⑨想知道自己一共有多少种路径可以选择,因为⑨的智商只有⑨,她自己肯定没法算出来啦。你能帮帮⑨吗?
Input
本体有多组数据。每组数据第一行为n,m(2<=n,m<=50) 接下来为n行m列的矩阵,表示在每个区域⑨逗留的时间t(0<=t<=1000)。
Output
每组数据输出一行,表示路径总数(保证小于2^63)。
Sample Input
3 3
1 2 3
1 2 3
1 2 3
3 3
1 1 1
1 1 1
1 1 1
1 2 3
1 2 3
1 2 3
3 3
1 1 1
1 1 1
1 1 1
Sample Output
1
6
6
Source
2013 Anhui College Student Programming Contest--Hu Yue
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
int map[51][51];
int t[51][51];//t为花费
long long s[51][51];
int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
int n,m;
struct pp{
int x,y;
};
queue<pp> que;
int flag[100][100];
void bfs()//广搜 计算各个点到 (n,m)的最短距离
{
pp a,b;
int dx,dy,i,spend;
a.x=n-1;
a.y=m-1;
t[n-1][m-1]=map[n-1][m-1];
que.push(a);
while(!que.empty())
{
b=que.front();
que.pop();
for(int i=0;i<4;i++)
{
dx=b.x+dir[i][0];
dy=b.y+dir[i][1];
if(dx>=0&&dx<n&dy>=0&&dy<m)
{
spend=t[b.x][b.y]+map[dx][dy];
if(t[dx][dy]==-1||spend<t[dx][dy])
{
a.x=dx;
a.y=dy;
t[dx][dy]=spend;
que.push(a);
}
}
}
}
}
long long dfs(int x,int y)//深搜 统计路径个数
{
int i;
if(s[x][y]>-1)
return s[x][y];
if(x==n-1&&y==m-1)
return 1;
s[x][y]=0;
for(i=0;i<4;i++)
{
int xx=x+dir[i][0];
int yy=y+dir[i][1];
if(xx>=0&&xx<n&&yy>=0&&yy<m)
{
if(t[x][y]>t[xx][yy])//如果当前结点到终点的距离大于 下个个结点到终点的距离
{//说明这个结点还有价值 继续深搜
s[x][y]+=dfs(xx,yy);
}
}
}
return s[x][y];
}
int main()
{
int i,j;
while(cin>>n>>m)
{
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
cin>>map[i][j];
t[i][j]=-1;
}
}
while(!que.empty()) que.pop();//出队
memset(s,-1,sizeof(s));
bfs();
dfs(0,0);
cout<<s[0][0]<<endl;
}
return 0;
}