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

第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;
}
相关推荐
漂流瓶jz36 分钟前
UVA-1613 K度图的着色 题解答案代码 算法竞赛入门经典第二版
算法·深度优先·图论·贪心·aoapc·算法竞赛入门经典·uva
Pniubi1 小时前
动态规划入门 ( - 力扣509斐波那契数)
算法·动态规划
吴长建先生重名了2 小时前
GitHub Actions部署报表系统踩坑记:幂等性与限
算法
贝壳6903 小时前
一个2026年2月才上传的库,凭什么敢碰2009年就有人写烂的题目
算法
贝壳6903 小时前
同一道三亿位选型题,三个AI给了我三个答案,我把它们拉进同一台机器复跑
算法
岑梓铭6 小时前
《考研408数据结构》第八章(排序)复习笔记
数据结构·笔记
青少儿编程课堂6 小时前
蓝桥杯青少组图形化 + 全国青少年信息素养大赛 + 电子学会图形化考级:校园大富翁经营闯关解析
c++·python·算法·bfs·信息学竞赛
在所不辞兄6 小时前
为什么在新能源汽车电驱与热管理开发中,AI驱动的数字孪生和数据驱动仿真正在部分替代对物理台架与实车标定的依赖?
人工智能·深度学习·神经网络·算法·机器学习
I_belong_to_jesus17 小时前
C++关于分支预测的优化1
开发语言·c++·算法