HDU 1142 A Walk Through the Forest Djkstra单源最短路

来源:互联网 发布:淘宝运营推广视频 编辑:程序博客网 时间:2024/05/03 03:41

一道最短路径 Djkstra(求单源最短路径) 模版题目,不过后期需要搜索处理才能枚举出答案。

完了,普通的DFS试了一发还会超时,需要用记忆化搜索,要保存中间所得的结果,减少递归进行的次数,实际上这个重复递归计算的次数是我们无法想象的大。

记忆化处理过后就AC了!


传送门:HDU-1142-A-Walk-Through-the-Forest

// dj + 记忆化搜索#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;const int inf = 999999999;int map[1005][1005];int dis[1005],vis[1005];int path[1005];int n,m;void Dijkstra(int src) {    int i,j,minn,pos;    memset(vis,0,sizeof(vis));    for(i = 0; i<=n; i++)        dis[i] = map[src][i];    vis[src] = 1;    for(i = 1; i<=n; i++) {        minn = inf;        pos = 0;        for(j = 1; j<=n; j++) {            if(minn > dis[j] && !vis[j])                minn = dis[pos = j];        }        vis[pos] = 1;        for(j = 1; j<=n; j++)            if(dis[j]>dis[pos]+map[pos][j] && !vis[j])                dis[j] = dis[pos]+map[pos][j];    }}// 记忆化搜索 - path[] 进行中间结果记忆化int DFS(int src) {    if(path[src] != -1) // 如果这个点已dfs        return path[src]; // 直接返回这个点的方案数    if(src == 2)  // 走到了2点即house        return 1;    path[src] = 0;    for(int i = 1; i<=n; i++) {        // dis[i] < dis[src] i到重点的距离小于src到终点的距离 && 有联通路        // 走到i点        if(dis[i]<dis[src] && map[src][i]!=inf)            path[src] += DFS(i);    }    return path[src];}// 不记忆化搜索 会超时间/*int DFS(int src) {    if(src == 2)  // 走到了2点即house        return 1;    int sum = 0;    for(int i = 1; i<=n; i++) {        if(dis[i]<dis[src] && map[src][i]!=inf)            sum += DFS(i);    }    return sum;}*/int main(){    int i,j,x,y,z;    while(~scanf("%d",&n),n) {        scanf("%d",&m);        for(i = 0; i<=n; i++) {            for(j = 0; j<=n; j++)                map[i][j] = inf;            map[i][i] = 0;        }        for(i = 0; i<m; i++) {            scanf("%d%d%d",&x,&y,&z);            map[x][y] = map[y][x] = z;        }        // 技巧 : 反过来找2为单源起点的到各个点的最短路径 - 存在 dis[] 数组中        Dijkstra(2);        memset(path,-1,sizeof(path));        printf("%d\n",DFS(1));    }    return 0;}
1 0