[AHOI2017初中组]guide

题目描述

农场主John最近在网上买了一辆新车,在购买汽车配件时,John不小心点了两次“提交”按钮。导致汽车上安装了两套GPS系统,更糟糕的是John在使用GPS导航时,两套系统常常给出不同的路线。从地图上看,John居住的地区有N(2 ≤ N ≤ 100,000)个十字路口和M(1 ≤ M ≤ 500,000)条限定通行方向的道路。第i条道路连接路口 A_i (1 ≤ A_i ≤ N)和B_i (1 ≤ B_i ≤ N),两个路口之间可能连接有多条道路。允许双向通的道路是将两条单向通⾏的道路隔开所形成的。

John的家在路口1位置,农场在路口N的位置。John可以沿着系列单向道路从家驾车到农场。所有GPS系统的底层地图信息都是⼀样的,区别仅在于对每一条道路的通⾏时间计算不同。对于第i条道路第一套GPS系统计算通行时间为P_i个单位时间,而第二套GPS系统则给出Q_i个单位时间。(所有道路的通行时间都是范围在1到100,000之间的整数)John想要驾车从家到农场。可是,一路上GPS系统总是不厌其烦的提醒John(请从路口X开往路口Y),这是由于John选取了某套GPS系统建议的路径,而另一套GPS系统则认为这不是从路口X到农场的最短路径。我们称之为GPS系统的抱怨。

请你计算一下如果John选择合适的路径到达农场能听到的最少GPS系统的抱怨数 。如果John经过某条道路两套GPS系统都发出抱怨,则抱怨总数加2。

输入输出格式

输入格式:

第一行,两个整数N和M。

接下来M行,其中第i行描述了道路i的信息,A_i B_i P_i Q_i。

输出格式:

一个整数,表示John一路上能听到的最小抱怨数。

输入输出样例

输入样例#1: 
5 7 3 4 7 1
1 3 2 20
1 4 17 18
4 5 25 3
1 2 10 1
3 5 4 14
2 4 6 5
输出样例#1: 
1

闲话:
2017考完这题后,我们老师才开始讲最短路。。。然后讲了1个多月。。。

分析:
本题算法除了最短路我也不知道还能想到什么了。。。
主要在于要跑3遍SPFA,首先2遍按两套系统给出的不同值算最短路,然后按每条边的抱怨值重新构图,再做一次最短路求出答案。

CODE:
 1 #include <cmath>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <iostream>
 5 #include <algorithm>
 6 #include <queue>
 7 using namespace std;
 8 const int M=1000005;
 9 const long long oo=(1ll<<61);
10 int nxt[M],to[M],head[M],inq[M],tot,rtot;
11 int rnxt[M],rto[M],rhead[M];
12 int adj1[M],adj2[M],adj3[M];
13 long long dist1[M],dist2[M],dist3[M];
14 int n,m;
15 void add(int u,int v,int w1,int w2){
16     nxt[++tot]=head[u];head[u]=tot;to[tot]=v;
17     adj1[tot]=w1;adj2[tot]=w2;
18     return;
19 }
20 void radd(int u,int v,int w){
21     rnxt[++rtot]=rhead[u];rhead[u]=rtot;rto[rtot]=v;adj3[rtot]=w;
22     return;
23 }
24 void spfa1(){
25     queue <int> Q;
26     Q.push(n);inq[n]=1;dist1[n]=0;
27     while (!Q.empty()){
28         int top=Q.front();Q.pop(),inq[top]=0;
29         for (int i=head[top];i;i=nxt[i])
30             if (dist1[top]+adj1[i]<dist1[to[i]]){
31                 dist1[to[i]]=dist1[top]+adj1[i];
32                 if (!inq[to[i]]) Q.push(to[i]),inq[to[i]]=1;
33                 }
34         }
35     return;
36     }
37 void spfa2(){
38     queue <int> Q;
39     Q.push(n);inq[n]=1;dist2[n]=0;
40     while (!Q.empty()){
41         int top=Q.front();Q.pop(),inq[top]=0;
42         for (int i=head[top];i;i=nxt[i])
43             if (dist2[top]+adj2[i]<dist2[to[i]]){
44                 dist2[to[i]]=dist2[top]+adj2[i];
45                 if (!inq[to[i]]) Q.push(to[i]),inq[to[i]]=1;
46                 }
47         }
48     return;
49     }
50 void spfa3(){
51     queue <int> Q;
52     Q.push(1);inq[1]=1;dist3[1]=0;
53     while (!Q.empty()){
54         int top=Q.front();Q.pop(),inq[top]=0;
55         for (int i=rhead[top];i;i=rnxt[i])
56             if (dist3[top]+adj3[i]<dist3[rto[i]]){
57                 dist3[rto[i]]=dist3[top]+adj3[i];
58                 if (!inq[rto[i]]) Q.push(rto[i]),inq[rto[i]]=1;
59                 }
60         }
61     return;
62     }
63 int main(){
64     scanf("%d%d",&n,&m);
65     for (int i=1;i<=n;i++) dist1[i]=dist2[i]=dist3[i]=oo;
66     for (int i=1;i<=m;i++){
67         int u,v,w1,w2;
68         scanf("%d%d%d%d",&u,&v,&w1,&w2);
69         add(v,u,w1,w2);
70     }
71     spfa1();spfa2();
72     for (int i=1;i<=n;i++)
73         for (int j=head[i];j;j=nxt[j])
74             radd(to[j],i,(dist1[i]+adj1[j]>dist1[to[j]])+(dist2[i]+adj2[j]>dist2[to[j]]));
75     spfa3();
76     cout<<dist3[n];
77     return 0;
78     }


 
原文地址:https://www.cnblogs.com/kanchuang/p/11150124.html