已经提交 已经通过

9.83%

Total Submission:417

Total Accepted:41

题目描述

爬山是wlswls最喜欢的活动之一。

在一个神奇的世界里,一共有nn座山,mm条路。

wlswls初始有kk点体力,在爬山的过程中,他所处的海拔每上升1m1m,体力会减11点,海拔每下降1m1m,体力会加一点。

现在wlswls想从11号山走到nn号山,在这个过程中,他的体力不能低于00,所以他可以事先花费一些费用请dlsdls把某些山降低,将一座山降低ll米需要花费l*ll∗l的代价,且每座山的高度只能降低一次。因为wlswls现在就在11号山上,所以这座山的高度不可降低。

wlswls从11号山到nn号山的总代价为降低山的高度的总代价加上他走过的路的总长度。

wlswls想知道最小的代价是多少。

 
 

输入描述

第一行三个整数nn,mm,kk。

接下来一行nn个整数,第ii个整数h_ihi​表示第ii座山的高度。

接下来mm行,每行三个整数xx,yy,zz表示xyxy之间有一条长度为zz的双向道路。

经过每条路时海拔是一个逐步上升或下降的过程。

数据保证11号山和nn号山联通。

1 \leq n, k, h_i, z \leq 1000001≤n,k,hi​,z≤100000

1 \leq m \leq 2000001≤m≤200000

1 \leq x, y \leq n1≤x,y≤n

x \neq yx̸​=y

输出描述

一行一个整数表示答案。

样例输入 1

4 5 1
1 2 3 4
1 2 1
1 3 1
1 4 100
2 4 1
3 4 1

样例输出 1

6

去年的题,其实当时写了,两个板子,有一个过了一个没过,今天又看到这道题了,打算改一改,改了一下午,一直过不去,最后发现初始化有点问题,有一个是比数据范围大一点点的初始化,一个是直接memset初始化,因为以前memset初始化写超时过,所以就没在意,结果发现就是这里错了。。。啊啊啊啊啊啊啊啊啊,哭死。初始化的时候,要比最大值大一点初始化,for循环的初始化,改成1e18就可以。之所以memset是对的,是因为填充的时候,inf比实际的要大。

思路就是把体力值加到路径里面,然后想一想,发现有几分道理,只要往上走才会掉值,emnnnn,反正感觉有点怪,就是把体力值加到路径里面然后跑个最短路就可以了。

两个版本的dijkstra,随便看着玩吧。。。

代码1(短一点):

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<bitset>
#include<cassert>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<deque>
#include<iomanip>
#include<list>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii; const double PI=acos(-1.0);
const double eps=1e-;
const ll mod=1e9+;
const int inf=0x3f3f3f3f;
const int maxn=1e5+;
const int maxm=+;
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); int n,m,k;
int cnt=,head[maxn<<];
bool vist[maxn];
ll dis[maxn],body[maxn];
priority_queue<pair<ll,int>,vector<pair<ll,int> >,greater<pair<ll,int> > >q; struct node{
int v,nex;
ll w;
}edge[maxn<<]; void add(int u,int v,ll w)
{
edge[cnt].v=v;
edge[cnt].w=w;
edge[cnt].nex=head[u];
head[u]=cnt++;
} void dijkstra(int s)
{
dis[s]=;//到自己的最短距离直接设为0
q.push(make_pair(,s));
while(!q.empty()){//队列非空
int u=q.top().second;q.pop();
vist[u]=true;
for(int i=head[u];~i;i=edge[i].nex){
int v=edge[i].v;
ll w=edge[i].w+(body[v]>k?(body[v]-k)*(body[v]-k):);
if(dis[v]>dis[u]+w){//满足条件更新距离
dis[v]=dis[u]+w;
//p[v]=u;//保存路径
q.push(make_pair(dis[v],v));//把更新完的值压入队列
}
}
}
} int main()
{
memset(head,-,sizeof(head));//初始化数组
memset(vist,false,sizeof(vist));
memset(dis,inf,sizeof(dis));
cin>>n>>m>>k;
for(int i=;i<=n;i++)
cin>>body[i];
for(int i=;i<=m;i++){
int u,v;ll w;
cin>>u>>v>>w;
add(u,v,w);
add(v,u,w);//无向图相互可达 有向图一次就好
}
k+=body[];
dijkstra();
cout<<dis[n]<<endl;
}

代码2(队友的板子,哈哈哈哈):

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<bitset>
#include<cassert>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<deque>
#include<iomanip>
#include<list>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii; const double PI=acos(-1.0);
const double eps=1e-;
const ll mod=1e9+;
const int inf=0x3f3f3f3f;
const int maxn=1e5+;
const int maxm=+;
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); int n,m,k;
int done[maxn],p[maxn];//d[i]表示i点到起点s的最短路距离,p[i]表示起点s到i的最短路径与i点相连的上一条边
ll d[maxn],body[maxn];//done[u]==1表示u点到起点s的最短路已经找到 struct edge{ //边结构体;
int from,to;
ll dis;
}; vector<edge> edges; //边集 无向图 边数*2
vector<int> g[maxn]; //g数组存的是边的序号 struct mindis{ //压入优先队列的结构体 因为d[u]和u要绑定起来 才可标记 u是否已确定最短路;
ll d;
int u; bool operator <(const mindis& rhs)const{
return d>rhs.d; //距离最小值优先 距离相等无所谓 随便一个先出 边权是正的 两个会依次访问 不会影想结果
}
}; priority_queue<mindis> q; //优先队列 小顶堆 最小值优先 void addedge(int from,int to,ll dis) //加边操作
{
edges.push_back((edge){from,to,dis}); //将边压入边集
int k=edges.size();
g[from].push_back(k-); //k-1为边序号 以后调用边集数组要从下标0开始 所以边的编号从0开始 将边序号压入已from为起点的数组
} void dijkstra(int s) //主算法
{
d[s]=; //到自己的最短距离直接设为0
q.push((mindis){,s});
while(!q.empty()){ //队列非空
mindis x=q.top(); //取当前最小值
q.pop();
int u=x.u;
if(done[u]==) continue; //已确定路径直接跳过
done[u]=; //标记 已确定
for(int i=;i<g[u].size();i++){
edge e=edges[g[u][i]]; //g[u][i]表示以u为起点的第i条边在边集edges中的下标
ll w=e.dis+(body[e.to]>k?(body[e.to]-k)*(body[e.to]-k):);
if(d[e.to]>d[u]+w){ //满足条件更新距离
d[e.to]=d[u]+w;
p[e.to]=g[u][i]; //保存路径
q.push((mindis){d[e.to],e.to}); //把更新完的值压入队列
}
}
}
} int main()
{
memset(done,,sizeof(done)); //初始化数组
memset(p,-,sizeof(p));
//memset(d,inf,sizeof(d));
cin>>n>>m>>k;
for(int i=;i<=n;i++) //把距离初始化为 inf 不能用memset 自己估算一下路径最长有多长 inf定义大一点就好
d[i]=1e18;
for(int i=;i<=n;i++)
cin>>body[i];
for(int i=;i<=m;i++){
int u,v;ll w;
cin>>u>>v>>w;
addedge(u,v,w);
addedge(v,u,w); //无向图相互可达 有向图一次就好
}
k+=body[];
dijkstra();
cout<<d[n]<<endl;
}

好想找队友聊天,但是放假了,不能打扰,超乖.jpg。

溜了,我姐的狗窝没有吃的,要饿死了(;´д`)ゞ

Comet OJ CCPC-Wannafly Winter Camp Day1 (Div2, online mirror) F.爬爬爬山-最短路(Dijkstra)(两个板子)+思维(mdzz...) zhixincode的更多相关文章

  1. 2020 CCPC Wannafly Winter Camp Day1 Div.1&amp F

    #include<bits/stdc++.h> #define forn(i, n) for (int i = 0; i < int(n); i++) #define fore(i, ...

  2. 2020 CCPC Wannafly Winter Camp Day1 C. 染色图

    2020 CCPC Wannafly Winter Camp Day1 C. 染色图 定义一张无向图 G=⟨V,E⟩ 是 k 可染色的当且仅当存在函数 f:V↦{1,2,⋯,k} 满足对于 G 中的任 ...

  3. 2020 CCPC Wannafly Winter Camp Day1 - I. K小数查询(分块)

    题目链接:K小数查询 题意:给你一个长度为$n$序列$A$,有$m$个操作,操作分为两种: 输入$x,y,c$,表示对$i\in[x,y] $,令$A_{i}=min(A_{i},c)$ 输入$x,y ...

  4. CCPC-Wannafly Winter Camp Day1 (Div2, online mirror) A,B,C,E,F,I,J

    https://www.zhixincode.com/contest/7/problems A题 分类讨论 当B有点需要经过时 穿梭的花费肯定为2*k,也可以发现,我们要找到包含所有需要经过的点(不含 ...

  5. CCPC-Wannafly Winter Camp Day1 (Div2 ABCFJ) 待补...

    Day1 Div2 场外链接 按题目顺序~ A 机器人 传送门 题意:有两条平行直线A.B,每条直线上有n个点,编号为1~n.在同一直线上,从a站点到b站点耗时为两点间的距离.存在m个特殊站点,只有在 ...

  6. CCPC Wannafly Winter Camp Div2 部分题解

    Day 1, Div 2, Prob. B - 吃豆豆 题目大意 wls有一个\(n\)行\(m\)列的棋盘,对于第\(i\)行第\(j\)列的格子,每过\(T[i][j]\)秒会在上面出现一个糖果, ...

  7. 2019 CCPC-Wannafly Winter Camp Day1 (Div2, onsite)

    solve:4/11 补题:6/11 A 机器人 补题:zz 这是一道分类讨论的题目,有一个规律就是如果必须要从第一个区到第二个区,那么最多转区两次(1到2一次,2到1一次),然后分类讨论即可,只要细 ...

  8. CCPC-Wannafly Winter Camp Day1 (Div2, onsite) A B C E F I J

    A 机器人 链接:https://www.cometoj.com/contest/7/problem/A?problem_id=92 思路: 分两大类讨论: 1. B区没有点: (1)点都在起点左边 ...

  9. CCPC-Wannafly Winter Camp Day1 (Div2, onsite)

    Replay Dup4: 要是不挂机,再多仔细想想就好了 J确实自闭好久,一直在想正确性,最后数据错了,喵喵喵? 还是要保证充足的休息啊,中间睡了一小会儿,也不知道睡了多久,醒来他们就又过了一道 要发 ...

随机推荐

  1. js实现游戏转盘抽奖

    <!DOCTYPE html> <html> <head> <title>js抽奖</title> <meta charset=&qu ...

  2. 整数中1出现的次数(从1到n整数中1出现的次数)

    整数中1出现的次数(从1到n整数中1出现的次数) 题目描述 求出1 ~ 13的整数中1出现的次数,并算出100 ~ 1300的整数中1出现的次数?为此他特别数了一下1 ~ 13中包含1的数字有1.10 ...

  3. LightOJ 1062 - Crossed Ladders 基础计算几何

    http://www.lightoj.com/volume_showproblem.php?problem=1062 题意:问两条平行边间的距离,给出从同一水平面出发的两条相交线段长,及它们交点到水平 ...

  4. 【比赛】洛谷夏令营NOIP模拟赛

    Day1 第一题 水题 第二题 题意:一个n*m的字符矩阵从左上到右下,经过字符形成回文串的路径数.n≤500 回文串,考虑两段往中间DP. f[k][x][y]表示走了k步,左上点横坐标为x,右下点 ...

  5. Vuejs - 单文件组件

    为什么需要单文件组件 在之前的实例中,我们都是通过 Vue.component 或者 components 属性的方式来定义组件,这种方式在很多中小规模的项目中还好,但在复杂的项目中,下面这些缺点就非 ...

  6. 【洛谷 P1452】 Beauty Contest (二维凸包,旋转卡壳)

    题目链接 旋转卡壳模板题把. 有时间再补总结吧. #include <cstdio> #include <cmath> #include <algorithm> u ...

  7. eCharts_数据过多底部滚动条实现数据展示

    效果图: 实现原理: 1.添加dataZoom属性 效果实现代码: <!DOCTYPE html> <html> <head> <meta charset=& ...

  8. js_微信分享,监听点击分享,分享成功,取消分享,分享失败回调

    2017-06-13 见代码: function weixinShare() { var links = links = "www.youku.com"; common.get_o ...

  9. mouseover/mouseenter/mouseout/mouseleave的区别

    mouseover:鼠标指针穿过被选元素或其子元素,均会触发事件 mouseenter:鼠标指针穿过被选元素时才触发事件 mouseout:鼠标指针离开被选元素或其子元素则触发事件 mouseleav ...

  10. 一个基于时间注入的perl小脚本

    use strict; use warnings; use LWP::Simple; my %table_and_leng; ;;$count++){ #print "Test Table: ...