CCPC-Wannafly Winter Camp Day1 (Div2, onsite) F 爬爬爬山 [dijkstra]

爬山是wlswls最喜欢的活动之一。
在一个神奇的世界里,一共有n座山,m条路。wls初始有k点体力,在爬山的过程中,他所处的海拔每上升1m,体力会减1点,海拔每下降1m,体力会加一点。
现在wls想从1号山走到n号山,在这个过程中,他的体力不能低于0,所以他可以事先花费一些费用请dls把某些山降低,将一座山降低l米需要花费
l*l 的代价,且每座山的高度只能降低一次。因为wls现在就在1号山上,所以这座山的高度不可降低。wls从1号山到n号山的总代价为降低山的高度的总代价加上他走过的路的总长度。
wls想知道最小的代价是多少。

脑子第一反应是能量守恒 迷wa 上白书板子写过了
预处理下 然后跑 dijkstra n可以到100000 加堆
(wls 居然吐槽好多队 dj得名字写得千奇百怪 其实我也不记得这么拼写啦 23333)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 200000+5;

int n,m;
ll k;

typedef pair<ll,int> P;
vector<P> G[maxn];
priority_queue<P,vector<P>,greater<P> > que;

ll dis[maxn];
ll h[maxn];

void dj() {
	memset(dis,0x3f,(n+3)*sizeof(ll));
	dis[1]=0;
	que.push(P(0,1));
	while(!que.empty()) {
		P tp=que.top();
		que.pop();
		int u=tp.second,v;
		if(dis[u]<tp.first) continue;
		for(int i=0; i<G[u].size(); i++) {
			P tmp=G[u][i];
			v=G[u][i].second;
			if(dis[v]>dis[u]+tmp.first) {
				dis[v]=dis[u]+tmp.first;
				que.push(P(dis[v],v));
			}
		}
	}
	cout<<dis[n]<<endl;
}

int main() {
	scanf("%d %d %lld",&n,&m,&k);
	for(int i=0; i<n; i++) scanf("%lld",&h[i+1]);
	k+=h[1];
	int st,ed;
	ll co;
	for(int i=0; i<m; i++) {
		scanf("%d %d %lld",&st,&ed,&co);

		if(h[ed]>k) G[st].push_back(P(co+(h[ed]-k)*(h[ed]-k),ed));
		else G[st].push_back(P(co,ed));

		if(h[st]>k) G[ed].push_back(P(co+(h[st]-k)*(h[st]-k),st));
		else G[ed].push_back(P(co,st));
	}
	dj();
	return 0;
}
全部评论

相关推荐

拒绝无效加班的小师弟很中意你:求职意向没有,年龄、课程冗余信息可以删掉,需要提升项目经历。排版需要修改。
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务