同期:https://buringstraw.win/index.php/archives/43/
タイトル
ファーマージョンは最近、オンライン新しい車を購入しましたが、車のための余分な機能を選択するとき、彼急いで、彼は偶然に二回「送信」ボタンをクリックし、その結果、車は2つのGPSナビゲーションシステムを装備してしまいました!さらに悪いことに、2つのシステムは、多くの場合、FJが取るべきルートに関する相反する判断を下します。
FJが住んでいる地域の地図は、N個の交点から成る(2 <= N <= 10,000)
とM方向の道路(1 <= M <= 50,000)。道路は、私は交差点a_iを結ぶ(1 <= A_i <= N)
とB_iを(1 <= B_i <= N)
。複数の道路は交差点の同じ対を接続することができ、双方向道路が(one permitting two-way travel)
反対方向に2本の別々の方向の道路で表されます。FJの家は、交差点1に位置し、彼の農場は、方向道路のシリーズに沿って移動することによって、彼の家から農場に到達することが可能である交差点N.に位置しています。
上述したように、両方のGPSユニットは、同じ基本マップを使用しています。しかし、彼らはそれぞれの道路に沿って旅行時間のための異なる概念を持っています。道路iは最初のGPSユニットに応じて横断する時間のP_I単位をとり、時間のQ_Iユニットは第二ユニットに係るトラバースします(each travel time is an integer in the range 1..100,000)
。
FJは、ファームに彼の家から移動したいと考えています。しかし、各GPSユニットは大声FJ道路以下の任意の時間文句(say, from intersection X to intersection Y)
GPSユニットは、ファームにXからの最短経路の一部ではないと考えています(it is even possible that both GPS units can complain, if FJ takes a road that neither unit likes)
。
FJは、彼が適切に彼のルートを選択した場合、彼が受け取ることができ、総苦情の可能な最小数を決定するのに役立ちます。FJ道路をたどるときに、両方のGPSユニットが訴える場合、この合計に向かって+2としてカウント。
考え
それは次のn最短経路の各点と各点の最短の辺に対して決定spfaできるようGPS1はそれぞれと2つの抗図のGPS2内蔵
し、各エッジのグラフFJ、初期重みを構築します次のエッジと最も短い警告時間に同じGPSを1だけデクリメントされた場合に2は、警告の数を示しています。
コード
#include<cstdio>
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
const int MAXN = 10000 + 5;
int n, m;
struct mp {
struct ed {
int to, w, nex;
} e[MAXN * 6];
int newp;
int head[MAXN], fa[MAXN], d[MAXN];
bool inq[MAXN];
void lineAdd (int p1, int p2, int w) {
++newp;
e[newp].to = p2;
e[newp].w = w;
e[newp].nex = head[p1];
head[p1] = newp;
}
void spfa (int s) {
memset(inq, 0, sizeof(inq));
memset(d, 0x3f, sizeof(d));
queue<int> q;
q.push(s);
d[s] = 0;
while (!q.empty()) {
int u = q.front();
q.pop();
inq[u] = 0;
for (int i = head[u]; i; i = e[i].nex) {
int y = e[i].to;
if (d[u] + (e[i].w) < d[y]) {
d[y] = d[u] + e[i].w;
fa[y] = i;
if (!inq[y]) {
q.push(y);
inq[y] = 1;
}
}
}
}
}
};
mp g1, g2, fj;
void spfa_for_fj(void) {
memset(fj.inq, 0, sizeof(fj.inq));
memset(fj.d, 0x3f, sizeof(fj.d));
queue<int> q;
q.push(1);
fj.d[1] = 0;
while (!q.empty()) {
int u = q.front();
q.pop();
fj.inq[u] = 0;
for (int i = fj.head[u]; i; i = fj.e[i].nex) {
int y = fj.e[i].to, w = fj.e[i].w;
if (g1.fa[u] == i) --w;
if (g2.fa[u] == i) --w;
if (fj.d[u] + w < fj.d[y]) {
fj.d[y] = fj.d[u] + w;
if (!fj.inq[y]) {
q.push(y);
fj.inq[y] = 1;
}
}
}
}
}
int main (void) {
scanf("%d%d", &n, &m);
for (int i = 1; i <= m; ++i) {
int p1, p2, w1, w2;
scanf("%d%d%d%d", &p1, &p2, &w1, &w2);
g1.lineAdd(p2, p1, w1);
g2.lineAdd(p2, p1, w2);
fj.lineAdd(p1, p2, 2);
}
g1.spfa(n);
g2.spfa(n);
spfa_for_fj();
printf("%d\n", fj.d[n]);
fclose(stdin);
fclose(stdout);
return 0;
}