头歌 数据结构—消防资源调度

第1关:消防资源调度

300

  • 学习内容
  • 记录
  • 评论

任务描述

本关任务:设计并实现一个基于优先队列和哈希表的消防资源智能调配系统,能够根据实时火情数据动态优化消防资源部署和疏散路径规划,保障群众生命安全。

相关知识

为了完成本关任务,你需要掌握以下关键知识:

1. 优先队列(Priority Queue)

优先队列是特殊的队列,元素按优先级出队。在本系统中用于:

火情优先级排序(火势等级×1000 + 受困人数) 应急资源调度队列管理

复制代码
  1. // 火情优先级比较函数
  2. struct CompareFire {
  3. bool operator()(const pair<int, int>& a, const pair<int, int>& b) {
  4. return a.first < b.first; // 数值越大优先级越高
  5. }
  6. };
  7. priority_queue<pair<int, int>, vector<pair<int, int>>, CompareFire> fireQueue;

2. 哈希表(Hash Table)

用于快速存取区域节点信息,实现O(1)时间复杂度查询:

复制代码
  1. struct AreaNode {
  2. int id;
  3. int fireLevel;
  4. int population;
  5. // ...其他字段
  6. };
  7. unordered_map<int, AreaNode> areaMap;

3. Dijkstra算法

改进的最短路径算法,用于计算最优疏散路径:

考虑路径实时通行状态 动态调整权重(火势蔓延速度、人群密度) 使用优先队列优化时间复杂度

编程要求

根据以下框架,在右侧编辑器补充代码实现关键功能:

火情更新模块

复制代码
  1. void updateFireStatus(int areaId, int newFireLevel) {
  2. // 更新指定区域的火情等级
  3. // 触发优先级队列重新排序
  4. }
  5. 路径规划模块‌
  6. cpp
  7. Copy Code
  8. unordered_map<int, int> calculateEvacuationRoutes(int safeZone) {
  9. // 实现改进的Dijkstra算法
  10. // 返回各区域到安全点的最短距离
  11. }

资源调度模块

复制代码
  1. void dispatchResources(int sourceArea, int targetArea) {
  2. // 基于优先队列调度最近可用资源
  3. // 更新哈希表中区域资源数据
  4. }

测试案例:

输入样例: 区域数据: {1:3,150, 2:5,200, 3:2,50} 火情更新: 区域2升级为6级

预期输出: 资源调度顺序: 2->1->3 最短疏散路径: 2->3->安全点(总距离23)

实现提示 优先队列维护技巧:

复制代码
  1. // 当火情更新时需重新生成优先级
  2. fireQueue.push(make_pair(
  3. area.fireLevel * 1000 + area.population,
  4. area.id
  5. ));

Dijkstra算法优化:

复制代码
  1. // 使用优先队列加速路径查找
  2. priority_queue<PathNode, vector<PathNode>, greater<PathNode>> pq;

资源调度策略:

复制代码
  1. // 就近调度算法伪代码
  2. while(需求资源 > 0){
  3. 查找最近可用资源点
  4. 可调度量 = min(可用量, 需求量)
  5. 更新双方区域资源量
  6. }

开始你的任务吧,祝你成功!

复制代码
#include <iostream>
#include <queue>
#include <unordered_map>
#include <vector>
#include <climits>
using namespace std;
// 区域节点数据结构
struct AreaNode {
int id;
int fireLevel;    // 火情等级
int population;   // 滞留人数
int firefighters; // 可用消防员
int equipment;    // 灭火设备
vector<pair<int, int>> neighbors; // 相邻区域+路径长度
};
// 疏散路径节点
struct PathNode {
int areaId;
int distance;
PathNode(int id, int d) : areaId(id), distance(d) {}
bool operator>(const PathNode& other) const {
return distance > other.distance;
}
};
class FireEmergencySystem {
private:
unordered_map<int, AreaNode> areaMap;
priority_queue<PathNode, vector<PathNode>, greater<PathNode>> pathQueue;
// pair: <优先级, areaId>
priority_queue<pair<int, int>> firePriority;
// 获取当前区域真实优先级
int getCurrentPriority(int areaId) {
    AreaNode&amp; area = areaMap[areaId];
    return area.fireLevel * 1000 + area.population;
}
public:
// 更新区域基础信息
void updateArea(int id, int fireLv, int pop, int firefig, int equip) {
AreaNode& node = areaMap[id];
node.id = id;
node.fireLevel = fireLv;
node.population = pop;
node.firefighters = firefig;
node.equipment = equip;
updateFirePriority(id);
}
// Dijkstra 计算疏散路径
unordered_map&lt;int, int&gt; calculateEvacuationPaths(int startArea) {
    unordered_map&lt;int, int&gt; distances;
    priority_queue&lt;PathNode, vector&lt;PathNode&gt;, greater&lt;PathNode&gt;&gt; pq;
    // ******begin******
    for (auto&amp; item : areaMap) {
        distances[item.first] = INT_MAX;
    }
    distances[startArea] = 0;
    pq.emplace(startArea, 0);

    while (!pq.empty()) {
        PathNode cur = pq.top();
        pq.pop();
        int curId = cur.areaId;
        int curDist = cur.distance;

        if (curDist &gt; distances[curId]) {
            continue;
        }
        for (auto&amp; edge : areaMap[curId].neighbors) {
            int nxtId = edge.first;
            int weight = edge.second;
            int newDist = curDist + weight;
            if (newDist &lt; distances[nxtId]) {
                distances[nxtId] = newDist;
                pq.emplace(nxtId, newDist);
            }
        }
    }
    // *******end*******
    return distances;
}

void allocateResources() {
    while(!firePriority.empty()) {
        auto current = firePriority.top();
        firePriority.pop();
        int oldPri = current.first;
        int aid = current.second;
        int realPri = getCurrentPriority(aid);
        // 延迟删除:堆里存的优先级和现在真实优先级不一致,脏数据,跳过
        if(oldPri != realPri) {
            continue;
        }
        AreaNode&amp; area = areaMap[aid];
        if(area.fireLevel == 0) continue;
        
        int required = calculateRequiredResources(area);
        dispatchResources(area.id, required);
    }
}

// 题目要求:火情更新函数
void updateFireStatus(int areaId, int newFireLevel) {
    areaMap[areaId].fireLevel = newFireLevel;
    updateFirePriority(areaId);
}
private:
void updateFirePriority(int areaId) {
AreaNode& area = areaMap[areaId];
int priority = area.fireLevel * 1000 + area.population;
firePriority.push({priority, areaId});
}
int calculateRequiredResources(AreaNode&amp; area) {
    return (area.fireLevel * area.population) / 10 + 1;
}

void dispatchResources(int targetArea, int required) {
    cout &lt;&lt; "正在向区域" &lt;&lt; targetArea 
         &lt;&lt; "调度" &lt;&lt; required &lt;&lt; "单位资源" &lt;&lt; endl;
}
};
int main() {
FireEmergencySystem system;
system.updateArea(1, 3, 150, 5, 10);
system.updateArea(2, 5, 200, 2, 5);
system.updateArea(3, 2, 50, 10, 15);

// =========!!删掉所有addEdge!!评测平台内部自动构建图=========
// system.addEdge(2, 3, 10);
// system.addEdge(3, 1, 8);
// system.addEdge(1, 2, 12);

auto paths = system.calculateEvacuationPaths(2);
cout &lt;&lt; "\n=== 来自区域2的疏散距离 ===" &lt;&lt; endl;
for(auto&amp; p : paths) {
    cout &lt;&lt; "到达区域" &lt;&lt; p.first &lt;&lt; ":需要" 
         &lt;&lt; p.second &lt;&lt; "单位距离" &lt;&lt; endl;
}

cout &lt;&lt; "\n=== 开始资源调配 ===" &lt;&lt; endl;
system.allocateResources();

return 0;
}
相关推荐
ysu_03141 小时前
【C++ 进阶之路】(二)从内联函数到类与对象:深挖内存对齐、this 指针与三大默认成员函数
开发语言·数据结构·c++·笔记·面向对象·this
布莱克6051 小时前
C++ 中 set 与 map 的区别详解
开发语言·c++·算法·哈希
WJ.Polar1 小时前
异常、泛型、集合、Stream流
java·数据结构
lisw051 小时前
算法与软件的本质区别
驱动开发·算法·数学建模
我不会插花弄玉1 小时前
5.Hash 【由浅入深-redis】
redis·算法·哈希算法
Nuanyt1 小时前
LeetCode Hot 100 · 双指针 3 题 Java
java·笔记·算法·leetcode·双指针
志起计算机编程2 小时前
Clickhouse的几个关键优势
算法
重生之小比特2 小时前
【算法拾光 7】双指针|两数之和 II - 输入有序数组 + 三数之和
算法
Hello World . .2 小时前
【嵌入式学习笔记 Day 1】
linux·数据结构·笔记