题目概况

题目描述

给你一个\(N\)个点的有向图,可能有重边.

有两个\(GPS\)定位系统,分别认为经过边\(i\)的时间为\(P_i\),和\(Q_i\).

每走一条边的时候,如果一个系统认为走的这条边不是它认为的最短路,就会受到警告一次.

两个系统是分开警告的,就是说当走的这条边都不在两个系统认为的最短路范围内,就会受到2次警告.

如果边\((u,v)\)不在\(u\)到\(n\)的最短路径上,这条边就受到一次警告,求从\(1\)到\(n\)最少受到多少次警告。

输入格式

第一行,两个整数,\(n,m\),表示\(n\)个点,\(m\)条边.

接下来有\(m\)行,每一行四个整数,\(a_i,b_i,c_i,d_i\).

表示有一条有向边\((a_i,b_i)\),然后第一个导航认为消耗时间为\(c_i\),第二导航认为消耗时间为\(d_i\)

输出格式

一行整数,输出最少警告数

数据范围

\[2 \le N \le 10,000 \\\\1 \le M \le 50,000 \\\\1 \le a_i \le N \\\\1 \le b_i \le N \\\\1 \le c_i,d_i \le 100,000 \\\\
\]

算法解析

题意理解

  1. 两个\(GPS\),系统为你分别规划了一条最短路径.

  2. 一旦你不走其中一个\(GPS\)认为的最短路径上的边,就会警告你一次.

  3. 因此有可能两个\(GPS\)都警告你.


算法解析

首先,我们要找到两条最短路径.

  1. 因此我们需要知道任意节点到\(n\)号节点的最短路.

  2. 所以我们可以建反向图,从\(n\)号节点出发,分别按照两个GPS跑一次最短路,求出路径.

其次就是统计每条边上警告数量

  1. 我们可以考虑枚举每一条边.

  2. 然后针对两个不同的GPS系统

  3. 判断其权值是否是这条边两个节点的最短路长度

  4. 如果是表示位于最短路,否则不位于最短路.

最后,统计最少警告数量

  1. 根据上面的每条边的警告数量,再来一次最短路.

  2. 然后这道题目就解决完了,但是代码是真的一言难尽.


代码解析

#include<bits/stdc++.h>
using namespace std;
const int N=11000;
struct node
{
int v,w;
};
vector<node> f[N],g[N],ans[N];
int dis1[N],dis2[N],dis3[N],n,m,vis[N];
void spfa(vector<node> g[N],int d[],int x)//传入存储图的数组,最短路数组,起始点
{
for(int i=1; i<=n; i++)//记住这里一定不能使用memset,因为会失灵
d[i]=0x3f3f3f3f;
memset(vis,0,sizeof(vis));//这里可以memset,是因为是全局变量
d[x]=0;
queue<int> q;
q.push(x);
while (q.size())
{
int x=q.front();
q.pop();
vis[x]=0;
for (int i=0; i<g[x].size(); i++)//访问所有的出边
{
int y=g[x][i].v,w=g[x][i].w;
if (d[y]>d[x]+w)//三角形不等式,然后开始松弛
{
d[y]=d[x]+w;
if (!vis[y])
{
q.push(y);
vis[y]=1;
}
}
}
}
}
inline void init()
{
scanf("%d%d",&n,&m);
for(int i=1; i<=m; i++)
{
int a,b,c,d;
scanf("%d%d%d%d",&a,&b,&c,&d);
f[b].push_back({a,c});//这里是反向图建立,第一个导航
g[b].push_back({a,d});//记得将方向取反,第二个导航
}
spfa(f,dis1,n);//分别找到GPS距离
spfa(g,dis2,n);
for (int i=1; i<=n; i++)//对于每一个点
for (int j=0; j<f[i].size(); j++)//这个是针对每一条出边,f,g无所谓
{
int u=f[i][j].v,p=f[i][j].w,q=g[i][j].w,r=2;//u是抵达点,p是第一个导航的抵达点,q是第二个导航的抵达点
if (dis1[u]-dis1[i]==p) r--;//发现是在第一个导航最短路上,然后警告数-1
if (dis2[u]-dis2[i]==q) r--;//发现是在第二个导航最短路上,然后警告数-1
ans[u].push_back({i,r});//存储边和权值
}
spfa(ans,dis3,1);
printf("%d\n",dis3[n]);
}
int main()
{
init();
return 0;
}

[USACO14OPEN]GPS的决斗Dueling GPS's的更多相关文章

  1. BZOJ 3538 == 洛谷 P3106 [USACO14OPEN]GPS的决斗Dueling GPS's

    P3106 [USACO14OPEN]GPS的决斗Dueling GPS's 题目描述 Farmer John has recently purchased a new car online, but ...

  2. Luogu P3106 [USACO14OPEN]GPS的决斗Dueling GPS's(最短路)

    P3106 [USACO14OPEN]GPS的决斗Dueling GPS's 题意 题目描述 Farmer John has recently purchased a new car online, ...

  3. 洛谷 3106 [USACO14OPEN]GPS的决斗Dueling GPS's 3720 [AHOI2017初中组]guide

    [题解] 这两道题是完全一样的. 思路其实很简单,对于两种边权分别建反向图跑dijkstra. 如果某条边在某一种边权的图中不是最短路上的边,就把它的cnt加上1.(这样每条边的cnt是0或1或2,代 ...

  4. 2018.07.22 洛谷P3106 GPS的决斗Dueling GPS's(最短路)

    传送门 图论模拟题. 这题直接写3个(可以压成一个)spfa" role="presentation" style="position: relative;&q ...

  5. USACO Dueling GPS's

    洛谷 P3106 [USACO14OPEN]GPS的决斗Dueling GPS's 洛谷传送门 JDOJ 2424: USACO 2014 Open Silver 2.Dueling GPSs JDO ...

  6. BZOJ3538: [Usaco2014 Open]Dueling GPS

    3538: [Usaco2014 Open]Dueling GPS Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 59  Solved: 36[Subm ...

  7. GPS校时器,GPS时钟装置,NTP网络时间服务器

    GPS校时器,GPS时钟装置,NTP网络时间服务器 GPS校时器,GPS时钟装置,NTP网络时间服务器 GPS校时器,GPS时钟装置,NTP网络时间服务器 GPS校时器,GPS时钟装置,NTP网络时间 ...

  8. 部署-GPS授时系统:GPS授时系统

    ylbtech-部署-GPS授时系统:GPS授时系统 GPS授时系统是针对自动化系统中的计算机.控制装置等进行校时的高科技产品,GPS授时产品它从GPS卫星上获取标准的时间信号,将这些信息通过各种接口 ...

  9. [USACO14OPEN] Dueling GPS's[最短路建模]

    题目描述 Farmer John has recently purchased a new car online, but in his haste he accidentally clicked t ...

随机推荐

  1. ArcMap 制作广州 18 级地图切片需要多少时间?

    制作地图切片包会随着级别的上升,瓦片数量会指数级地上升,所需的计算时间也是指数级的. 但是 ArcMap 并不会提示时间信息,只有一个圈没完没了地转... 就在这无聊地等待中,我写了这篇帖子. 电脑配 ...

  2. Java学习笔记-Lambda表达式

    Lambda表达式支持将代码块作为方法参数,Lambda表达式允许使用简洁的代码来创建只有一个抽象方法的接口(这种接口被称为函数是接口)的实例 意义 自从Java 8开始,Java支持Lambda表达 ...

  3. 鼠标拖拉div宽度

    先看效果 先进入页面 当鼠标停留在中间div时,鼠标变成双箭头 点击拖拉 往右边拉 往最左边拉 代码 <!DOCTYPE html> <html> <head> & ...

  4. 《深入理解计算机系统》☞hello world背后的故事

    一步到位的hello world 首先一个简单的C语言版本的hello world例子,保存在文件hello.c中. #include <stdio.h> int main() { pri ...

  5. Python 命名规范总结

    Python推荐命名规范: 模块名和包名采用小写字母并且以下划线分隔单词的形式: 如:browser_driver 类名或异常名采用每个单词首字母大写的方式: 如:BasePage, Keyboard ...

  6. RMI(远程方法调用)

    Remote Method Invocation  跨虚拟机间调用 使用 RMI 技术可轻松将 服务提供者(Service Provider)与 服务消费者(Service Consumer)进行分离 ...

  7. springboot service dockerfile

    FROM java:8u111 MAINTAINER ianthony7@163.com # 定义变量 ENV WORK_DIR /opt ENV LOG_DIR /data/logs EXPOSE ...

  8. Java手写简单HashMap一(包括增加,查找,toString,泛型)

    @Java 300 学习总结 HashMap底层采用实现采用了哈希表,结合了"数组和链表". 原理如图 一.定义HashMap类. 首先需要定义一个节点来存储数据,构成链表结构. ...

  9. docker-get拉取镜像

    docker-get Let you get all docker images without having network problem. Install curl -kLO https://s ...

  10. java中锁的应用

    锁作为并发共享数据,保证一致性的工具,在JAVA平台有多种实现(如 synchronized(重量级) 和 ReentrantLock(轻量级)等等 ) .这些已经写好提供的锁为我们开发提供了便利. ...