[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     }
 
计算机