第1关:消防资源调度
300
- 学习内容
- 记录
- 评论
任务描述
本关任务:设计并实现一个基于优先队列和哈希表的消防资源智能调配系统,能够根据实时火情数据动态优化消防资源部署和疏散路径规划,保障群众生命安全。
相关知识
为了完成本关任务,你需要掌握以下关键知识:
1. 优先队列(Priority Queue)
优先队列是特殊的队列,元素按优先级出队。在本系统中用于:
火情优先级排序(火势等级×1000 + 受困人数) 应急资源调度队列管理
// 火情优先级比较函数struct CompareFire {bool operator()(const pair<int, int>& a, const pair<int, int>& b) {return a.first < b.first; // 数值越大优先级越高}};priority_queue<pair<int, int>, vector<pair<int, int>>, CompareFire> fireQueue;
2. 哈希表(Hash Table)
用于快速存取区域节点信息,实现O(1)时间复杂度查询:
struct AreaNode {int id;int fireLevel;int population;// ...其他字段};unordered_map<int, AreaNode> areaMap;
3. Dijkstra算法
改进的最短路径算法,用于计算最优疏散路径:
考虑路径实时通行状态 动态调整权重(火势蔓延速度、人群密度) 使用优先队列优化时间复杂度
编程要求
根据以下框架,在右侧编辑器补充代码实现关键功能:
火情更新模块
void updateFireStatus(int areaId, int newFireLevel) {// 更新指定区域的火情等级// 触发优先级队列重新排序}路径规划模块cppCopy Codeunordered_map<int, int> calculateEvacuationRoutes(int safeZone) {// 实现改进的Dijkstra算法// 返回各区域到安全点的最短距离}
资源调度模块
void dispatchResources(int sourceArea, int targetArea) {// 基于优先队列调度最近可用资源// 更新哈希表中区域资源数据}
测试案例:
输入样例: 区域数据: {1:3,150, 2:5,200, 3:2,50} 火情更新: 区域2升级为6级
预期输出: 资源调度顺序: 2->1->3 最短疏散路径: 2->3->安全点(总距离23)
实现提示 优先队列维护技巧:
// 当火情更新时需重新生成优先级fireQueue.push(make_pair(area.fireLevel * 1000 + area.population,area.id));
Dijkstra算法优化:
// 使用优先队列加速路径查找priority_queue<PathNode, vector<PathNode>, greater<PathNode>> pq;
资源调度策略:
// 就近调度算法伪代码while(需求资源 > 0){查找最近可用资源点可调度量 = min(可用量, 需求量)更新双方区域资源量}
开始你的任务吧,祝你成功!
#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& 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<int, int> calculateEvacuationPaths(int startArea) {
unordered_map<int, int> distances;
priority_queue<PathNode, vector<PathNode>, greater<PathNode>> pq;
// ******begin******
for (auto& 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 > distances[curId]) {
continue;
}
for (auto& edge : areaMap[curId].neighbors) {
int nxtId = edge.first;
int weight = edge.second;
int newDist = curDist + weight;
if (newDist < 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& 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& area) {
return (area.fireLevel * area.population) / 10 + 1;
}
void dispatchResources(int targetArea, int required) {
cout << "正在向区域" << targetArea
<< "调度" << required << "单位资源" << 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 << "\n=== 来自区域2的疏散距离 ===" << endl;
for(auto& p : paths) {
cout << "到达区域" << p.first << ":需要"
<< p.second << "单位距离" << endl;
}
cout << "\n=== 开始资源调配 ===" << endl;
system.allocateResources();
return 0;
}