This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
#define cerr if(false) cerr
#define watch(x) cerr << (#x) << " is " << (x) << endl;
#define endl '\n'
#define ld long double
#define int long long
#define pii pair<int, int>
#define fi first
#define se second
#define sz(a) (int)(a).size()
#define all(x) (x).begin(), (x).end()
const int maxn = 250;
const int maxm = 50500;
int n, m;
int u[maxm], v[maxm], c[maxm], d[maxm];
int dis[maxn][maxn];
// .fi = cost, .se = destination
multiset<pii> G[maxn];
multiset<int> mi[maxn][maxn];
int dist(int x, int y) {
cerr << "go from " << x << " -> " << y << endl;
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
if(i == j) {
dis[i][j] = 0;
} else {
dis[i][j] = 1e18;
}
}
}
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
if(mi[i][j].empty()) continue;
dis[i][j] = min(dis[i][j], *mi[i][j].begin());
}
}
for(int rep = 1; rep <= 10; rep++)
for(int k = 1; k <= n; k++) {
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
}
}
}
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
if(dis[i][j] == 1e18) cout << "I ";
else cerr << dis[i][j] << " ";
}
cerr << endl;
}
return dis[x][y];
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n >> m;
for(int i = 1; i <= m; i++) {
cin >> u[i] >> v[i] >> c[i] >> d[i];
cerr << "going from " << u[i] << " to " << v[i] << " w cost " << c[i] << endl;
G[u[i]].emplace(c[i], v[i]);
mi[u[i]][v[i]].emplace(c[i]);
}
watch(sz(G[2]))
// watch(ree)
int ans = 1e18;
ans = min(ans, dist(1, n)+dist(n, 1));
for(int i = 1; i <= m; i++) {
cerr << "trying " << i << endl;
// reverse
mi[u[i]][v[i]].erase(mi[u[i]][v[i]].lower_bound(c[i]));
mi[v[i]][u[i]].emplace(c[i]);
int to = dist(1, n);
int back = dist(n, 1);
watch(to)
watch(back)
watch(d[i]+to+back)
ans = min(ans, d[i] + to + back);
// put back
mi[v[i]][u[i]].erase(mi[v[i]][u[i]].lower_bound(c[i]));
mi[u[i]][v[i]].emplace(c[i]);
cerr << endl;
}
if(ans == 1e18) {
cout << -1 << endl;
} else {
cout << ans << endl;
}
}
/*
simulate inverting each edge
4 5
1 2 4 4
1 3 2 1
4 3 1 2
4 1 6 1
2 4 2 5
-> 10
4 10
1 2 4 4
1 2 4 4
1 3 2 1
1 3 2 1
4 3 1 2
4 3 1 2
4 1 6 1
4 1 6 1
2 4 2 5
2 4 2 5
-> 10
4 4
1 2 0 4
1 3 0 1
4 3 0 2
4 1 0 1
-> 2
4 5
1 2 4 4
1 3 2 4
4 3 1 5
4 1 6 1
2 4 2 5
-> 12
4 5
2 1 4 4
1 3 2 1
4 3 1 2
4 3 6 1
2 4 2 5
-> -1
Did you read the bounds?
Did you make typos?
Are there edge cases (N=1?)
Are array sizes proper?
Integer overflow?
DS reset properly between test cases?
Is using long longs causing TLE?
Are you using floating points?
*/
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |