[USACO14OPEN]GPS的决斗Dueling GPS's

题目概况

题目描述

给你一个\(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

原文地址:https://www.cnblogs.com/gzh-red/p/11822899.html

时间: 2024-11-05 20:42:33

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

洛谷 P3106 [USACO14OPEN]GPS的决斗Dueling GPS&#39;s

P3106 [USACO14OPEN]GPS的决斗Dueling GPS's 题目描述 Farmer John has recently purchased a new car online, but in his haste he accidentally clicked the "Submit" button twice when selecting extra features for the car, and as a result the car ended up equip

P3106 [USACO14OPEN]GPS的决斗Dueling GPS&#39;s

题面:https://www.luogu.org/problem/P3106 首先以n为起点两边spfa,之后再判断所有的边是否在最短路上,以警告次数作为边权再次spfa. Code: #include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> #include<queue> using namespace std;

P3106 GPS的决斗Dueling GPS&#39;s

目录 题目 思路 Code 同步:https://buringstraw.win/index.php/archives/43/ 题目 Farmer John has recently purchased a new car online, but in his haste he accidentally clicked the "Submit" button twice when selecting extra features for the car, and as a result

[USACO14OPEN] Dueling GPS&#39;s[最短路建模]

题目描述 Farmer John has recently purchased a new car online, but in his haste he accidentally clicked the "Submit" button twice when selecting extra features for the car, and as a result the car ended up equipped with two GPS navigation systems! Ev

BZOJ3538: [Usaco2014 Open]Dueling GPS

3538: [Usaco2014 Open]Dueling GPS Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 59  Solved: 36[Submit][Status] Description Farmer John has recently purchased a new car online, but in his haste he accidentally clicked the "Submit" button twice w

USACO 2014 US Open Dueling GPS&#39;s /// SPFA

题目大意: 给定n个点m条边的有向图 有两个GPS 分别认为 A[i]到B[i] 的一条边的花费是P[i].Q[i] 当当前走的边不是GPS认为的最短路上的边就会被警告 即两个GPS都不认为是最短路上的边时 会被警告两次 求从点1走到点n被警告次数最少是多少次 https://blog.csdn.net/oakley_/article/details/52510465 按P[i]反向建图 再从n跑最短路到1 然后遍历所有的边判断将不是最短路的边C[i]+1 Q[i]也同样 最后按C[i]从1跑最

P3106 [USACO14OPEN]GPS的决斗(最短路)

化简:够简的了.....但是!翻译绝对有锅. 这个最短路是从n到每个点的单源最短路,也就是最短路径树. 那么,思路就很明确了.建两个图,然后跑两边SPFA,记录下最短路径. 然后,对于两点之间的边,如果最短路不经过它,那么最终图边权+1: 然后在最终图上(边权为0,1,2)跑一遍SPFA即可. 一开始我想复杂了,在想怎么记录路径,怎么重构图.balabala. 然后发现,怎么才能让两点不在最短路径上呢? SPFA的松弛操作,依据是三角不等式.于是,如果两点之间的最短路的距离如果不等于边权(也就是

【GPS】SAP测试GPS模块拿不到sensor数据

问题描述: 有时候做SAP测试时发现SAP没有生效.检查sap.conf/izat.conf 配置文件没有问题,测试方法也严格按照高通建议来做,但QXDM 的F3 窗口搜索" sdp"并没有看到sensor数据注入modem GPS引擎. 解决办法: 在sap.conf中设置SENSOR_CONTROL_MODE=1(FORCE_ON),然后抓取"开机+发起GPS定位"的日志.这个测试可以在室内进行,不需要定位成功,主要目的是观察GPS引擎打开后有没有相关的注册和s

Android附近基站+Wifi+IP+GPS多渠道定位方案

前言: 在移动客户端的开发中,地理位置定位是一个非常重要的环节,有些时候用户可能会限制web app或者Android app的一些权限,或者由于信号不佳的原因无法获得准确的GPS位置,甚至为了省电,用户可能对开启GPS开关可能会有抵触情绪.但是不能因为GPS的种种限制就放弃了对用户位置的追踪.要通过一切能发送出信号的物体尽可能准确的获取到用户的位置,有时可以牺牲一些精度,对于大数据和用户地区分布分析来说,有一个大体的位置已经够分析人员使用,而且绕开GPS的重重壁垒,为数据的完整性提供可靠方案