题目链接:

[GXOI/GZOI2019]旅行者

我们考虑每条边的贡献,对每个点求出能到达它的最近的感兴趣的城市(设为$f[i]$,最短距离设为$a[i]$)和它能到达的离它最近的感兴趣的城市(设为$g[i]$,最短距离设为$b[i]$)。

那么每条边$(u,v,w)$的贡献就是$a[u]+w+b[v]$,用这个值去更新答案即可(这个值代表$f[u]$到$g[v]$的最短路长度)。

但要注意一条边能更新答案需要满足$f[u]\neq g[v]$,因为要保证起点和终点不同。

手画一下就可以知道最短路径上的边至少有一条会更新答案,即不可能发生最短路径上每条边的$f[u]=g[v]$。

#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<bitset>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
#define pr pair<ll,int>
using namespace std;
int tot;
int head[100010];
int to[600010];
int nex[600010];
int val[600010];
ll ans;
int tim;
int n,m,k;
int u[500010];
int v[500010];
int w[500010];
ll d[100010];
ll c[100010];
int f[100010];
int g[100010];
int a[100010];
int vis[100010];
priority_queue< pr,vector<pr>,greater<pr> >q;
void init()
{
memset(head,0,sizeof(head));
memset(val,0,sizeof(val));
memset(nex,0,sizeof(nex));
memset(to,0,sizeof(to));
memset(f,0,sizeof(f));
memset(c,0,sizeof(c));
memset(g,0,sizeof(g));
memset(d,0,sizeof(d));
memset(v,0,sizeof(v));
memset(w,0,sizeof(w));
memset(u,0,sizeof(u));
tot=0;
}
void add(int x,int y,int z)
{
nex[++tot]=head[x];
head[x]=tot;
to[tot]=y;
val[tot]=z;
}
void dijkstra(int opt)
{
tot=0;
memset(vis,0,sizeof(vis));
memset(head,0,sizeof(head));
memset(f,0,sizeof(f));
for(int i=1;i<=n;i++)
{
d[i]=1ll<<60;
}
for(int i=1;i<=k;i++)
{
d[a[i]]=0;
f[a[i]]=a[i];
q.push(make_pair(d[a[i]],a[i]));
}
for(int i=1;i<=m;i++)
{
if(!opt)
{
add(u[i],v[i],w[i]);
}
else
{
add(v[i],u[i],w[i]);
}
}
while(!q.empty())
{
int now=q.top().second;
q.pop();
if(vis[now])
{
continue;
}
vis[now]=1;
for(int i=head[now];i;i=nex[i])
{
if(d[to[i]]>d[now]+val[i])
{
d[to[i]]=d[now]+val[i];
f[to[i]]=f[now];
q.push(make_pair(d[to[i]],to[i]));
}
}
}
}
void solve()
{
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&u[i],&v[i],&w[i]);
}
for(int i=1;i<=k;i++)
{
scanf("%d",&a[i]);
}
dijkstra(0);
for(int i=1;i<=n;i++)
{
c[i]=d[i],g[i]=f[i];
}
dijkstra(1);
ll ans=1ll<<60;
for(int i=1;i<=m;i++)
{
if(g[u[i]]&&f[v[i]]&&g[u[i]]!=f[v[i]])
{
ans=min(ans,c[u[i]]+d[v[i]]+w[i]);
}
}
printf("%lld\n",ans);
}
int main()
{
scanf("%d",&tim);
while(tim--)
{
init();
solve();
}
}

[LOJ3087][GXOI/GZOI2019]旅行者——堆优化dijkstra的更多相关文章

  1. P5304 [GXOI/GZOI2019]旅行者

    题目地址:P5304 [GXOI/GZOI2019]旅行者 这里是官方题解 一个图 \(n\) 点 \(m\) 条边,里面有 \(k\) 个特殊点,问这 \(k\) 个点之间两两最短路的最小值是多少? ...

  2. BZOJ 3040 最短路 (堆优化dijkstra)

    这题不是裸的最短路么?但是一看数据范围就傻了.点数10^6,边数10^7.这个spfa就别想了(本来spfa就是相当不靠谱的玩意),看来是要用堆优化dijkstra了.但是,平时写dijkstra时为 ...

  3. UVA - 11374 - Airport Express(堆优化Dijkstra)

    Problem    UVA - 11374 - Airport Express Time Limit: 1000 mSec Problem Description In a small city c ...

  4. 【BZOJ5506】[GXOI/GZOI2019]旅行者(最短路)

    [BZOJ5506][GXOI/GZOI2019]旅行者(最短路) 题面 BZOJ 洛谷 题解 正着做一遍\(dij\)求出最短路径以及从谁转移过来的,反过来做一遍,如果两个点不由同一个点转移过来就更 ...

  5. BZOJ5415[Noi2018]归程——kruskal重构树+倍增+堆优化dijkstra

    题目描述 本题的故事发生在魔力之都,在这里我们将为你介绍一些必要的设定. 魔力之都可以抽象成一个 n 个节点.m 条边的无向连通图(节点的编号从 1 至 n).我们依次用 l,a 描述一条边的长度.海 ...

  6. 配对堆优化Dijkstra算法小记

    关于配对堆的一些小姿势: 1.配对堆是一颗多叉树. 2.包含优先队列的所有功能,可用于优化Dijkstra算法. 3.属于可并堆,因此对于集合合并维护最值的问题很实用. 4.速度快于一般的堆结构(左偏 ...

  7. POJ 3635 - Full Tank? - [最短路变形][手写二叉堆优化Dijkstra][配对堆优化Dijkstra]

    题目链接:http://poj.org/problem?id=3635 题意题解等均参考:POJ 3635 - Full Tank? - [最短路变形][优先队列优化Dijkstra]. 一些口胡: ...

  8. 【堆优化Dijkstra+字典序最短路方案】HDU1385-Minimum Transport Cost

    [题目大意] 给出邻接矩阵以及到达各个点需要付出的代价(起点和终点没有代价),求出从给定起点到终点的最短路,并输出字典序最小的方案. [思路] 在堆优化Dijkstra中,用pre记录前驱.如果新方案 ...

  9. 【bzoj5197】[CERC2017]Gambling Guide 期望dp+堆优化Dijkstra

    题目描述 给定一张n个点,m条双向边的无向图. 你要从1号点走到n号点.当你位于x点时,你需要花1元钱,等概率随机地买到与x相邻的一个点的票,只有通过票才能走到其它点. 每当完成一次交易时,你可以选择 ...

随机推荐

  1. SLAM+语音机器人DIY系列:(二)ROS入门——8.理解roslaunch在大型项目中的作用

    摘要 ROS机器人操作系统在机器人应用领域很流行,依托代码开源和模块间协作等特性,给机器人开发者带来了很大的方便.我们的机器人“miiboo”中的大部分程序也采用ROS进行开发,所以本文就重点对ROS ...

  2. 在嵌入式设备中使用 JavaScript 的前景

    by Conmajia PC上的JavaScript已经发展到ECMAScript 6(ES6),马上ES10都快出来了(虽然还是草案),但是硬件上的JS却很少听说.这几年手持设备/可穿戴设备的发展非 ...

  3. 初步认识Swiper_前端交互控制神器_滚动3D切换等特效简单制作

    前言: 本人在项目的工作中负责研发,页面及交互基本都是交给前端去做的.以前前端写的东西大概都知道,都是一些JS,CSS和HTML等的一些基本控制,都懂!但是今天前端突然做了一个具有特殊效果的DOM:页 ...

  4. ASP.NET应用程序服务器集群方案

    本文采用Nginx来实现ASP.NET程序集群化. 准备环境 首先准备Nginx环境,Windows版本下载链接:http://nginx.org/en/download.html 解压后文件格式如下 ...

  5. throw和throws的区别以及try,catch,finally在有return的情况下执行的顺序

    一,抛出异常有三种形式,一是throw,一个throws,还有一种系统自动抛异常.下面它们之间的异同. (1).系统自动抛异常 1.当程序语句出现一些逻辑错误.主义错误或类型转换错误时,系统会自动抛出 ...

  6. JavaScript基础-3

    3 运算符 按照个数分类可分为:一元运算符.二元运算符.三元运算符: 按照功能分类可分为:算数运算符.自增运算符.比较运算符.逻辑运算符.赋值运算符: 3.1 算数运算符 算术运算符包含了加减乘除,符 ...

  7. mac 卸载通过官网下载包安装的node

    sudo rm -rf /usr/local/{bin/{node,npm},lib/node_modules/npm,lib/node,share/man/*/node.*}

  8. 解决Geoserver请求跨域的几种思路

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景描述 跨域问题是浏览器同源安全制引起的特别常见的问题.不同前端语 ...

  9. name 'reload' is not defined解决方法

    今天在学习scrapy的时候,在网上找了一段代码,运行出了一点问题. 命令行报错: name 'reload' is not defined 原因是,python版本的问题 原代码如下: import ...

  10. Jenkins 使用Tfs 插件出现 MappingConflictException 错误问题解决

    FATAL: com.microsoft.tfs.core.clients.versioncontrol.exceptions.MappingConflictException: The path C ...