1010: 好坑的电子地图

本文详细解析了使用Dijkstra算法结合优先队列求解最短路径的问题,通过一个具体的例子,介绍了如何处理带权图中从起点到终点的最短路径计算,包括考虑节点等待时间的复杂情况。

题目描述
小明是今年参加复试的外校考生,他要去民主楼小礼堂签到。由于对中南大学校本部很不熟悉,小明找到了这边读书的好朋友鲁大师,不巧,鲁大师在忙着自由探索项目的结题工作,不能给他带路,只好给他发了一份半成品的电子地图。地图上只列出了校本部内的N个点,M条路,小明处于S点,民主楼小礼堂是T点。小明感谢鲁大师,当然只是在拿到地图的一瞬间,后面的情况让他知道这半成品到底有多坑。鲁大师制作的电子地图是带有语音提示功能的,但是在编号为奇数的点他要等1分钟才能告诉他具体怎么走,而在编号为偶数的点要等2分钟。现在告诉你地图的具体情况,小明想知道他能不能在A分钟内赶到民主楼小礼堂。

输入
输入数据有多组,每组占M+1行,第一行有5个数字N,M,S,T,A,接下来M行,每行三个数字u,v,t,代表每条路的两个顶点和步行时间。(输入数据保证不含重边0<N<M<1000)
输出
对于每组输入数据,输出一行,小明能在A分钟内赶到民主楼小礼堂输出YES和最少花费的时间,否则输出KENG

样例输入
4 3 1 4 10
1 2 1
3 2 2
3 4 3
5 4 2 4 7
1 2 5
5 4 2
3 5 1
2 3 1
样例输出
YES 10
KENG

思想:最短路径(Dijkstra+优先队列)

#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;

struct Node{
	int u,d;
	friend bool operator < (Node a,Node b){	  //重载排序函数(从小到大) 
    	return a.d>b.d;
	}
};
const int N = 1000,INF = 1e9;
int n,m,s,T,a;	//n为顶点数,m为边数,s为起点
int G[N][N],dist[N],vis[N];	

void Dijkstra(int s){	//s为起点 
	priority_queue<Node> q;	
	Node node;
	fill(dist,dist+n+1,INF);	//初始化最短距离为INF 
	memset(vis,0,sizeof(vis));
	dist[s] = 0;	//起点s到达自身的距离为0
	node.u = s,node.d = dist[s];
	q.push(node);	//将s入队 
	while(!q.empty()){	 //队列不为空,即s与剩下的结点连通 
		node = q.top();
		q.pop();
		int u = node.u;
		if(vis[u])  //若u已被访问过,说明当前 d并不是最小值,直接跳过
		    continue;
		vis[u] = 1;		//将u加入集合 
		//以u为中间结点检测剩余结点 
		for(int v=1;v<=n;v++){
			if(!vis[v] && G[u][v]){   //如果v未访问 && u能到达v
				int tmp = dist[u]+(u%2==0?2:1)+G[u][v];
				if(dist[v]>tmp){   //以u为中介点可以使dist[v]更优 
					dist[v] = tmp;	//优化dist[v] 
					node.u = v,node.d = dist[v];
					q.push(node);	//将更新的结点入队
				} 
			}
		}
	}
}

int main(){
	int u,v,w;
	while(~scanf("%d %d %d %d %d",&n,&m,&s,&T,&a)){
		memset(G,0,sizeof(G));
		for(int i=0;i<m;i++){
			scanf("%d %d %d",&u,&v,&w);
			G[u][v] = G[v][u] = w;	//有向带权图 
		}
		Dijkstra(s);
		if(dist[T]!=INF && dist[T]<=a){
			printf("YES %d\n",dist[T]);
		}else{
			printf("KENG\n");
		}
	}
	return 0;
}

对于29行代码的解答:
疑惑:有没有可能某个顶点u已经出队,但是在后面的操作中又入队,且这个时候的d[u]比之前出队的距离还要小,那么这个时候就应该更新与其相连的顶点,这里30行已经continue会不会有问题呢?怎么证明后面不会再有比之前已出队的d[u]小 ?
回答:当u出队以后,之后的d[u]不可能更小。因为只有当u是当前队列中d最小的结点时,才会出队,此时队列中其他的d[i]都比d[u]要大,那么假设i能到u,那样d[i] + G[i][u]也不可能比d[u]更小(因为d[u]已经是当前最小的了,而且dijkstra能解决的图边权一定要为正)
另一种求最短路径方法1009: 安全路径(做了一点改变,求最大安全系数),时间复杂度更高

考虑可再生能源出力不确定性的商业园区用户需求响应策略(Matlab代码实现)内容概要:本文围绕“考虑可再生能源出力不确定性的商业园区用户需求响应策略”展开,结合Matlab代码实现,研究在可再生能源(如风电、光伏)出力具有不确定性的背景下,商业园区如何制定有效的需求响应策略以优化能源调度和提升系统经济性。文中可能涉及不确定性建模(如场景生成与缩减)、优化模型构建(如随机规划、鲁棒优化)以及需求响应机制设计(如价格型、激励型),并通过Matlab仿真验证所提策略的有效性。此外,文档还列举了大量相关的电力系统、综合能源系统优化调度案例与代码资源,涵盖微电网调度、储能配置、负荷预测等多个方向,形成一个完整的科研支持体系。; 适合人群:具备一定电力系统、优化理论和Matlab编程基础的研究生、科研人员及从事能源系统规划与运行的工程技术人员。; 使用场景及目标:①学习如何建模可再生能源的不确定性并应用于需求响应优化;②掌握使用Matlab进行商业园区能源系统仿真与优化调度的方法;③复现论文结果或开展相关课题研究,提升科研效率与创新能力。; 阅读建议:建议结合文中提供的Matlab代码实例,逐步理解模型构建与求解过程,重点关注不确定性处理方法与需求响应机制的设计逻辑,同时可参考文档中列出的其他资源进行扩展学习与交叉验证。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值