#include<bits/stdc++.h>
using namespace std;
#define int long long
#define ii pair <int, int>
#define app push_back
#define all(a) a.begin(), a.end()
#define bp __builtin_popcount
#define ll long long
#define mp make_pair
#define f first
#define s second
#define Time (double)clock()/CLOCKS_PER_SEC
const int N = 1e5 + 7, INF = 1e18 + 7;
struct Edge {
int u, v, c, d;
} e[N];
struct Ed {
int v, c, i;
};
int n, m;
int dist1[N], par1[N], par_ed1[N], sec1[N], best1[N];
int distn[N], parn[N], par_edn[N], secn[N], bestn[N];
int tmp[N];
int dist1_rev[N], sec1_rev[N], best1_rev[N];;
int distn_rev[N], secn_rev[N], bestn_rev[N];
vector <Ed> g[N], gr[N];
int get1n(int u, int v) {
return dist1[u] + distn_rev[v];
}
int getn1(int u, int v) {
return distn[u] + dist1_rev[v];
}
int get1n(int i) {
return get1n(e[i].u, e[i].v) + e[i].c;
}
int getn1(int i) {
return getn1(e[i].u, e[i].v) + e[i].c;
}
void dj(int S, int *dist, vector <Ed> g[N], int par[N], int par_ed[N], int sec[N], int best[N]) {
for (int i = 0; i < N; ++i) {
dist[i] = INF;
best[i] = -1;
sec[i] = INF;
}
set <ii> ms;
dist[S] = 0;
ms.insert(mp(0, S));
while (ms.size()) {
int u = ms.begin()->s;
ms.erase(ms.begin());
for (auto e : g[u]) {
if (dist[u] + e.c < dist[e.v]) {
ms.erase(mp(dist[e.v], e.v));
sec[e.v] = dist[e.v];
dist[e.v] = dist[u] + e.c;
par[e.v] = u;
par_ed[e.v] = e.i;
best[e.v] = e.i;
ms.insert(mp(dist[e.v], e.v));
}
else {
sec[e.v] = min(sec[e.v], dist[u] + e.c);
}
}
}
}
int from1(int u, int ban) {
if (ban != best1[u])
return dist1[u];
else
return sec1[u];
}
int ton(int u, int ban) {
if (ban != bestn_rev[u])
return distn_rev[u];
else
return secn_rev[u];
}
int fromn(int u, int ban) {
if (ban != bestn[u])
return distn[u];
else
return secn[u];
}
int to1(int u, int ban) {
if (ban != best1_rev[u])
return dist1_rev[u];
else
return sec1_rev[u];
}
int dist1n_del[N], distn1_del[N];
vector <int> tree[N], add[N], del[N];
bool used[N];
const int LG = 20;
int to[N][LG], tin[N], tout[N], timer = 0;
void dfs1(int u, int p) {
to[u][0] = p;
for (int i = 1; i < LG; ++i)
to[u][i] = to[to[u][i - 1]][i - 1];
tin[u] = timer++;
for (int v : tree[u])
dfs1(v, u);
tout[u] = timer++;
}
bool anc(int u, int v) {
return tin[u] <= tin[v] && tout[v] <= tout[u];
}
int lca(int u, int v) {
if (anc(u, v))
return u;
for (int i = LG - 1; i >= 0; --i)
if (!anc(to[u][i], v))
u = to[u][i];
return to[u][0];
}
signed main() {
#ifdef HOME
freopen("input.txt", "r", stdin);
#else
ios_base::sync_with_stdio(0); cin.tie(0);
#endif
cin >> n >> m;
for (int i = 0; i < m; ++i) {
cin >> e[i].u >> e[i].v >> e[i].c >> e[i].d;
g[e[i].u].app({e[i].v, e[i].c, i});
gr[e[i].v].app({e[i].u, e[i].c, i});
}
dj(1, dist1, g, par1, par_ed1, sec1, best1);
dj(n, distn, g, parn, par_edn, secn, bestn);
dj(1, dist1_rev, gr, tmp, tmp, sec1_rev, best1_rev);
dj(n, distn_rev, gr, tmp, tmp, secn_rev, bestn_rev);
for (int i = 2; i <= n; ++i)
if (par1[i]) {
tree[par1[i]].app(i);
used[par_ed1[i]] = 1;
}
dfs1(1, 1);
for (int i = 0; i < m; ++i) {
if (anc(e[i].v, e[i].u))
continue;
if (!used[i]) {
int l = lca(e[i].u, e[i].v);
int x = get1n(i);
if (anc(l, n)) {
if (anc(e[i].u, n) && !anc(e[i].u, e[i].v)) {
add[e[i].u].app(x);
del[l].app(x);
}
else if (anc(e[i].v, n)) {
add[e[i].v].app(x);
del[l].app(x);
}
}
}
}
if (!par1[n]) {
for (int i = 0; i < N; ++i)
dist1n_del[i] = INF;
}
else {
for (int i = 0; i < N; ++i)
dist1n_del[i] = dist1[n];
int u = n;
multiset <int> ms = {INF};
while (u != 1) {
//cout << "up " << u << '\n';
for (int e : add[u]) {
ms.insert(e);
//cout << "insert " << e << '\n';
}
for (int e : del[u]) {
ms.erase(ms.find(e));
//cout << "erase " << e << '\n';
}
dist1n_del[par_ed1[u]] = *ms.begin();
u = to[u][0];
}
}
for (int i = 0; i < N; ++i) {
tree[i].clear();
add[i].clear();
del[i].clear();
}
memset(used, 0, sizeof used);
for (int i = 1; i < n; ++i)
if (parn[i]) {
tree[parn[i]].app(i);
used[par_edn[i]] = 1;
}
dfs1(n, n);
for (int i = 0; i < m; ++i) {
if (anc(e[i].v, e[i].u))
continue;
if (!used[i]) {
int l = lca(e[i].u, e[i].v);
int x = getn1(i);
if (anc(l, 1)) {
if (anc(e[i].u, 1) && !anc(e[i].u, e[i].v)) {
add[e[i].u].app(x);
del[l].app(x);
}
else if (anc(e[i].v, 1)) {
add[e[i].v].app(x);
del[l].app(x);
}
}
}
}
if (!parn[1]) {
for (int i = 0; i < N; ++i)
distn1_del[i] = INF;
}
else {
for (int i = 0; i < N; ++i)
distn1_del[i] = distn[1];
int u = 1;
multiset <int> ms = {INF};
while (u != n) {
for (int e : add[u])
ms.insert(e);
for (int e : del[u])
ms.erase(ms.find(e));
distn1_del[par_edn[u]] = *ms.begin();
u = to[u][0];
}
}
#ifdef HOME
for (int i = 0; i < m; ++i)
cout << dist1n_del[i] << ' ';
cout << '\n';
for (int i = 0; i < m; ++i)
cout << distn1_del[i] << ' ';
cout << '\n';
#endif
int ans = dist1[n] + distn[1];
for (int i = 0; i < m; ++i) {
int d1n = from1(e[i].v, i) + ton(e[i].u, i) + e[i].c;
int dn1 = fromn(e[i].v, i) + to1(e[i].u, i) + e[i].c;
d1n = min(d1n, dist1n_del[i]);
dn1 = min(dn1, distn1_del[i]);
ans = min(ans, d1n + dn1 + e[i].d);
}
if (ans > 1e12)
cout << "-1\n";
else
cout << ans << '\n';
}
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
19 ms |
23292 KB |
Output is correct |
2 |
Correct |
19 ms |
23292 KB |
Output is correct |
3 |
Correct |
20 ms |
23416 KB |
Output is correct |
4 |
Correct |
20 ms |
23416 KB |
Output is correct |
5 |
Correct |
20 ms |
23288 KB |
Output is correct |
6 |
Correct |
19 ms |
23288 KB |
Output is correct |
7 |
Correct |
19 ms |
23160 KB |
Output is correct |
8 |
Correct |
23 ms |
23160 KB |
Output is correct |
9 |
Correct |
22 ms |
23288 KB |
Output is correct |
10 |
Correct |
20 ms |
23416 KB |
Output is correct |
11 |
Correct |
20 ms |
23416 KB |
Output is correct |
12 |
Correct |
20 ms |
23416 KB |
Output is correct |
13 |
Correct |
19 ms |
23292 KB |
Output is correct |
14 |
Incorrect |
21 ms |
23416 KB |
Output isn't correct |
15 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
63 ms |
28664 KB |
Output is correct |
2 |
Correct |
62 ms |
28328 KB |
Output is correct |
3 |
Correct |
61 ms |
28280 KB |
Output is correct |
4 |
Correct |
21 ms |
23416 KB |
Output is correct |
5 |
Correct |
20 ms |
23288 KB |
Output is correct |
6 |
Correct |
21 ms |
23288 KB |
Output is correct |
7 |
Correct |
19 ms |
23160 KB |
Output is correct |
8 |
Correct |
19 ms |
23160 KB |
Output is correct |
9 |
Correct |
59 ms |
29032 KB |
Output is correct |
10 |
Correct |
57 ms |
28660 KB |
Output is correct |
11 |
Correct |
58 ms |
28664 KB |
Output is correct |
12 |
Correct |
59 ms |
28664 KB |
Output is correct |
13 |
Correct |
57 ms |
28664 KB |
Output is correct |
14 |
Correct |
56 ms |
28664 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
20 ms |
23416 KB |
Output is correct |
2 |
Correct |
20 ms |
23288 KB |
Output is correct |
3 |
Correct |
49 ms |
27128 KB |
Output is correct |
4 |
Correct |
20 ms |
23288 KB |
Output is correct |
5 |
Correct |
57 ms |
28152 KB |
Output is correct |
6 |
Correct |
19 ms |
23164 KB |
Output is correct |
7 |
Correct |
19 ms |
23160 KB |
Output is correct |
8 |
Correct |
53 ms |
28920 KB |
Output is correct |
9 |
Correct |
54 ms |
28896 KB |
Output is correct |
10 |
Incorrect |
59 ms |
28156 KB |
Output isn't correct |
11 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
19 ms |
23292 KB |
Output is correct |
2 |
Correct |
19 ms |
23292 KB |
Output is correct |
3 |
Correct |
20 ms |
23416 KB |
Output is correct |
4 |
Correct |
20 ms |
23416 KB |
Output is correct |
5 |
Correct |
20 ms |
23288 KB |
Output is correct |
6 |
Correct |
19 ms |
23288 KB |
Output is correct |
7 |
Correct |
19 ms |
23160 KB |
Output is correct |
8 |
Correct |
23 ms |
23160 KB |
Output is correct |
9 |
Correct |
22 ms |
23288 KB |
Output is correct |
10 |
Correct |
20 ms |
23416 KB |
Output is correct |
11 |
Correct |
20 ms |
23416 KB |
Output is correct |
12 |
Correct |
20 ms |
23416 KB |
Output is correct |
13 |
Correct |
19 ms |
23292 KB |
Output is correct |
14 |
Incorrect |
21 ms |
23416 KB |
Output isn't correct |
15 |
Halted |
0 ms |
0 KB |
- |