hdu 1142 A Walk Through the Forest

来源:互联网 发布:揭东军埔淘宝村 编辑:程序博客网 时间:2024/06/06 14:26
Problem Description
Jimmy experiences a lot of stress at work these days, especially since his accident made working difficult. To relax after a hard day, he likes to walk home. To make things even nicer, his office is on one side of a forest, and his house is on the other. A nice walk through the forest, seeing the birds and chipmunks is quite enjoyable.
The forest is beautiful, and Jimmy wants to take a different route everyday. He also wants to get home before dark, so he always takes a path to make progress towards his house. He considers taking a path from A to B to be progress if there exists a route from B to his home that is shorter than any possible route from A. Calculate how many different routes through the forest Jimmy might take.


Input
Input contains several test cases followed by a line containing 0. Jimmy has numbered each intersection or joining of paths starting with 1. His office is numbered 1, and his house is numbered 2. The first line of each test case gives the number of intersections N, 1 < N ≤ 1000, and the number of paths M. The following M lines each contain a pair of intersections a b and an integer distance 1 ≤ d ≤ 1000000 indicating a path of length d between intersection a and a different intersection b. Jimmy may walk a path any direction he chooses. There is at most one path between any pair of intersections.


Output
For each test case, output a single integer indicating the number of different routes through the forest. You may assume that this number does not exceed 2147483647


Sample Input

5 6
1 3 2
1 4 2
3 4 3
1 5 12
4 2 34
5 2 24
7 8
1 3 1
1 4 1
3 7 1
7 4 1
7 5 1
6 7 1
5 2 1
6 2 1
0



Sample Output

2

4


题意:求从1到2的不同的最短路径的个数,但是有一个要求:假设从a到b有路,而且从a到终点的距离是大于从b到终点的距离的话,就可以走a到b这条路。

首先我们先从终点2开始找终点到其他点的最短路径(Dijkstra),然后我们再递归的查找每个点到终点不同最短路径数(DFS)。

代码中有重要注释。

AC代码:

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#define INF 0x3f3f3f3fusing namespace std;int Map[1001][1001];int n, m, ans;int dis[1001], vis[1001];int path[1001];void dj(int s)  ///用迪杰斯特拉求从终点2到其他点的最短距离{    for(int i = 0; i <= n; i++)    {        dis[i] = Map[s][i];        vis[i] = 0;    }    vis[s] = 1;    int minn = INF, u;    for(int i = 1; i <= n; i++)    {        minn = INF, u = 0;        for(int j = 1; j <= n; j++)        {            if(!vis[j]&&minn > dis[j])            {                minn = dis[j];                u = j;            }        }        vis[u] = 1;        for(int j = 1; j <= n; j++)        {            if(!vis[j]&&dis[u] + Map[u][j] < dis[j])            {                dis[j] = dis[u] + Map[u][j];            }        }    }}int dfs(int k)   ///递归的查找每个点到终点的不同路径数{    if(path[k]!=0)   ///如果path[k]不等于0,说明已经被访问过,不用再访问,直接返回该点到终点2的不同最短路数即可        return path[k];      if(k == 2)  ///如果等于2 则是走道了终点  结束        return 1;    path[k] = 0;   ///初始化当前点到2的路径数位0条    for(int i = 1; i <= n; i++)    {        ///如果从a到b有路,且从a到终点的距离是大于从b到终点的距离的话,则可以从a走到b        ///也就是当前点到终点的距离是大于下一个点到终点的距离的        if(Map[k][i]!=INF&&dis[k] > dis[i])            path[k]+=dfs(i);    }    return path[k];}int main(){    while(~scanf("%d",&n)&&n)    {        scanf("%d",&m);        for(int i = 0; i <= n; i++)        {            for(int j = 0; j <= n; j++)            {                Map[i][j] = INF;            }            Map[i][i] = 0;        }        int x, y, l;        for(int i = 0; i < m; i++)        {           scanf("%d%d%d",&x, &y, &l);           Map[x][y] = Map[y][x] = l;        }        dj(2); ///用来求终点2到其他点的距离        memset(path, 0, sizeof(path));        int ans = dfs(1); ///用来找从1到2有几条不同的路        printf("%d\n",ans);    }    return 0;}


0 0
原创粉丝点击