andre_joy

导航

hdu 1428

地址:http://acm.hdu.edu.cn/showproblem.php?pid=1428

题意:问最短路径有多少条。

mark:首先bfs是用来确定每个点到终点的最短路径。dfs来确定有多少条相同的最短路径。

代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <queue>
#define LL long long

using namespace std;

typedef struct
{
    int a,b;
}qq;

const int N = 60;
const int INF = (1 << 31)-1;
int n;
int s[N][N], f[N][N], dis[N][N];
int tab[4][2] = {1, 0, -1, 0, 0, 1, 0, -1};
LL dp[N][N];

void bfs()
{
    queue <qq> q;
    qq q1,q2;
    q1.a = q1.b = n-1;
    q.push(q1);
    while(!q.empty())
    {
        q1 = q.front();
        q.pop();
        f[q1.a][q1.b] = 0;
        for(int i = 0; i < 4; i++)
        {
            q2.a = q1.a+tab[i][0];
            q2.b = q1.b+tab[i][1];
            if(q2.a >= 0 && q2.a < n && q2.b >= 0 && q2.b < n && dis[q2.a][q2.b] > dis[q1.a][q1.b]+s[q2.a][q2.b])
            {
                dis[q2.a][q2.b] = dis[q1.a][q1.b]+s[q2.a][q2.b];
                if(!f[q2.a][q2.b])
                {
                    q.push(q2);
                    f[q2.a][q2.b] = 1;
                }
            }
        }
    }
}

LL dfs(int x, int y)
{
    if(dp[x][y]) return dp[x][y];
    int xx,yy;
    for(int i = 0; i < 4; i++)
    {
        xx = x+tab[i][0];
        yy = y+tab[i][1];
        if(xx >= 0 && xx < n && yy >= 0 && yy < n && dis[xx][yy] < dis[x][y])
            dp[x][y] += dfs(xx, yy);
    }
    return dp[x][y];
}

int main()
{
    int i,j;
    while(~scanf("%d", &n))
    {
        for(i = 0; i < n; i++)    
            for(j = 0; j < n; j++)
            {
                scanf("%d", &s[i][j]);
                f[i][j] = 0;
                dis[i][j] = INF;
            }
        dis[n-1][n-1] = s[n-1][n-1];
        bfs();
        memset(dp, 0, sizeof(dp));
        dp[n-1][n-1] = 1;
        printf("%I64d\n", dfs(0, 0));
    }
    return 0;
}

posted on 2012-08-20 18:01  andre_joy  阅读(175)  评论(0编辑  收藏  举报