• PAT 甲级 1003 Emergency DFS


    地址 https://pintia.cn/problem-sets/994805342720868352/problems/994805523835109376

    题目的大意是

    输入一群城市之间(0~n-1)的路径和该城市拥有的救援队数目,再给与你起点城市的编号和终点城市的编号,
    
    请输出起点到终点城市的最短路径有几条,和最短路径上能收集的最大救援队的数目
    
    输入格式
    
    第一行4个数 n m s e.  n表示城市的个数(0~n-1)  , m表示城市之间的路径 , s表示起点城市的编号, e表示终点城市的编号
    
    第二行 有n个数字 表示每个城市拥有的救援队数目
    
    下面是m行 每行三个数字 a b l.   a表示一个城市编号 b表示一个城市编号 l表示两城市之间的距离(道路是双向的)
    
    输出格式
    
    输出两个 数字 j k.   j表示最短路径有多少条   k表示能收集的最大救援队数目 用空格隔开
    
    示例
    Sample Input:
    5 6 0 2
    1 2 1 5 3
    0 1 1
    0 2 2
    0 3 1
    1 2 1
    2 4 1
    3 4 1
    Sample Output:
    2 4

    解答

    考虑到数据范围不大 基本都在几百以内,可以直接DFS加上剪枝即可搞定

    想进一步深入学习的同学可以考虑学习图论算法

    使用DFS 尝试从0点出发 到终点2的各种走法,不断更新每个城市从0点出发能够达到的最短路径。

    如果当前达到X点的走法的路径比之前到达X点的走法的路径要长,那么这种走法就不需要继续尝试了,因为按照这种走法达到后面的点肯定不是最短路径(剪枝)

    if (currDis > dist[x]){return;}
    

     

    如果当前达到X点的走法的路径比之前到达X点的走法的路径相等,

    那么就需要记录达到该点的最短路径的个数,

    path[x]++;

    同时还需要更新下能收集到救援队数目

    sum[x]  = max(currSum,sum[x] );

    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <memory.h>
    
    using namespace std;
    
    const int N = 700;
    const int INF = 0x3f3f3f3f;
    
    int graph[N][N];
    int teams[N];
    
    int start = -1;
    int endp = -1;
    
    
    int n, m;
    
    int path[N];
    int dist[N];
    int sum[N];
    
    void dfs(int curr,int currDis, int currPath, int currSum)
    {
        //剪枝 当前走法走到curr点已经不可能更短了
        if (currDis > dist[curr]){return;}
    
        if (currDis < dist[curr]) {
            dist[curr] = currDis;
            sum[curr] = currSum;
            path[curr] = 1;
        }
        else if (currDis == dist[curr] ) {
            sum[curr]  = max(currSum,sum[curr] );
            path[curr]++;
        }
    
        if (curr == endp) { return; }
    
    
        for (int i = 0; i < n; i++) {
            if (i != curr && graph[curr][i] != INF) {
                //currPath++; 
                currSum += teams[i];
                currDis += graph[curr][i];
                dfs(i, currDis,currPath, currSum);
                //currPath--; 
                currSum-= teams[i];
                currDis -= graph[curr][i];
            }
        }
    
        return;
    }
    
    
    int main()
    {
        //接受输入 得到 城市的个数和路径的个数 已经起点城市和终点城市
        cin >> n >> m >> start >> endp;
        //得到输入的每个城市的救援队数目
        for (int i = 0; i < n; i++) {
            cin >> teams[i];
        }
        //初始化 图所有路径为最大值0x3f3f3f3f
        memset(graph,0x3f,sizeof(graph));
        memset(dist, 0x3f, sizeof dist);
        
        //得到两个城市之间的路径
        for (int i = 0; i < m; i++) {
            int a, b, l;
            cin >> a >> b >> l;
            graph[a][b] = min(graph[a][b],l);
            graph[b][a] = min(graph[b][a], l);
        }
    
        dfs(start,0,0, teams[start]);
        
        cout << path[endp] << " " << sum[endp] << endl;
    
        return 0;
    }
    作 者: itdef
    欢迎转帖 请保持文本完整并注明出处
    技术博客 http://www.cnblogs.com/itdef/
    B站算法视频题解
    https://space.bilibili.com/18508846
    qq 151435887
    gitee https://gitee.com/def/
    欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
    如果觉得不错,欢迎点赞,你的鼓励就是我的动力
    阿里打赏 微信打赏
  • 相关阅读:
    深入理解定时器系列第二篇——被誉为神器的requestAnimationFrame
    深入理解定时器系列第一篇——理解setTimeout和setInterval
    idea自动生成方法注释(含参数及返回值)
    敲最少的键,编最多的码
    「HAOI2016」食物链
    「SCOI2015」小凸玩矩阵
    后缀自动机详解
    「TJOI2019」大中锋的游乐场
    「TJOI2019」唱、跳、rap 和篮球
    「TJOI2019」甲苯先生的滚榜
  • 原文地址:https://www.cnblogs.com/itdef/p/14393729.html
Copyright © 2020-2023  润新知