#include <bits/stdc++.h>
using namespace std;
using ll = long long;
ll INF = 1e18;
ll MOD = 1e9 + 7;
struct zxc {
ll v;
ll cost;
ll revers;
};
struct node {
ll a, b, c, d;
};
ll n, m;
vector<vector<zxc>> g, rg;
vector<pair<ll, ll>> dxs(ll v) {
vector<pair<ll, ll>> dist(n, {INF, 0});
set<pair<ll, ll>> st;
dist[v].first = 0;
dist[v].second = 1;
st.insert({dist[v].first, v});
while (!st.empty()) {
ll u = st.begin()->second;
st.erase(st.begin());
for (auto to: g[u]) {
ll cnt = to.cost + dist[u].first;
if (dist[to.v].first > cnt) {
st.erase({dist[to.v].first, to.v});
dist[to.v].first = cnt;
dist[to.v].second = dist[u].second;
st.insert({dist[to.v].first, to.v});
} else {
if (dist[to.v].first == cnt) {
dist[to.v].second += dist[u].second;
}
}
}
}
return dist;
}
vector<pair<ll, ll>> dxs_r(ll v) {
vector<pair<ll, ll>> dist(n, {INF, 0});
set<pair<ll, ll>> st;
dist[v].first = 0;
dist[v].second = 1;
st.insert({dist[v].first, v});
while (!st.empty()) {
ll u = st.begin()->second;
st.erase(st.begin());
for (auto to: rg[u]) {
ll cnt = to.cost + dist[u].first;
if (dist[to.v].first > cnt) {
st.erase({dist[to.v].first, to.v});
dist[to.v].first = cnt;
dist[to.v].second = dist[u].second;
st.insert({dist[to.v].first, to.v});
} else {
if (dist[to.v].first == cnt) {
dist[to.v].second += dist[u].second;
}
}
}
}
return dist;
}
vector<vector<ll>> pp;
vector<vector<ll>> dd;
vector<ll> qq;
vector<ll> used;
vector<ll> color;
ll cv = 0;
void dfs(ll v) {
used[v] = 1;
for (auto to: pp[v]) {
if (used[to] == 0) {
dfs(to);
}
}
qq.push_back(v);
}
void bfs(ll v) {
used[v] = 1;
color[v] = cv;
for (auto to: dd[v]) {
if (used[to] == 0) {
bfs(to);
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
cin >> n >> m;
g.assign(n, {});
pp.assign(n, {});
dd.assign(n, {});
used.assign(n, 0);
color.assign(n, 0);
rg.assign(n, {});
vector<node> r(m);
vector<ll> bad;
for (ll i = 0; i < m; i++) {
ll a, b, c, d;
cin >> a >> b >> c >> d;
a--;
b--;
if (c == 0) {
pp[a].push_back(b);
dd[b].push_back(a);
}
r[i] = {a, b, c, d};
}
for (ll i = 0; i < n; i++) {
if (used[i] == 0) {
dfs(i);
}
}
std::reverse(qq.begin(), qq.end());
used.assign(n, 0);
for (ll i = 0; i < qq.size(); i++) {
if (used[qq[i]] == 0) {
bfs(qq[i]);
cv++;
}
}
for (ll i = 0; i < n; i++) {
color[i] = i;
}
for (ll j = 0; j < m; j++) {
r[j].a = color[r[j].a];
r[j].b = color[r[j].b];
ll a = r[j].a, b = r[j].b, c = r[j].c, d = r[j].d;
if (r[j].a == r[j].b)continue;
g[a].push_back({b, c, d});
rg[b].push_back({a, c, d});
}
vector<pair<ll, ll>> dist_l_a = dxs(color[0]);
vector<pair<ll, ll>> dist_r_a = dxs_r(color[0]);
vector<pair<ll, ll>> dist_l_b = dxs(color[n - 1]);
vector<pair<ll, ll>> dist_r_b = dxs_r(color[n - 1]);
ll answer = dist_l_a[color[n - 1]].first + dist_l_b[color[0]].first;
for (ll i = 0; i < m; i++) {
if (r[i].a == r[i].b)continue;
ll cnt = dist_l_a[r[i].b].first + r[i].d + r[i].c + dist_r_b[r[i].a].first + r[i].c + dist_l_b[r[i].b].first +
dist_r_a[r[i].a].first;
if (dist_l_b[r[i].b].second != dist_l_b[r[i].a].second && dist_l_a[r[i].b].second != dist_l_a[r[i].a].second) {
answer = min(answer, cnt);
} else {
if (answer > cnt) {
bad.push_back(i);
}
}
cnt = dist_l_a[r[i].b].first + r[i].d + r[i].c + dist_r_b[r[i].a].first + dist_l_b[color[0]].first;
if (dist_l_b[color[0]].second != dist_l_b[r[i].a].second * dist_r_a[r[i].b].second) {
answer = min(answer, cnt);
} else {
if (answer > cnt) {
bad.push_back(i);
}
}
cnt = r[i].d + r[i].c + dist_l_b[r[i].b].first +
dist_r_a[r[i].a].first + dist_l_a[color[n - 1]].first;
if (dist_l_a[color[n - 1]].second != dist_l_a[r[i].a].second * dist_r_b[r[i].b].second) {
answer = min(answer, cnt);
} else {
if (answer > cnt) {
bad.push_back(i);
}
}
}
if (!bad.empty()) {
std::sort(bad.begin(), bad.end());
bad.resize(std::unique(bad.begin(), bad.end()) - bad.begin());
}
for (ll i = 0; i < bad.size(); i++) {
g.assign(n, {});
for (ll j = 0; j < m; j++) {
if (r[j].a == r[j].b)continue;
ll a = r[j].a, b = r[j].b, c = r[j].c, d = r[j].d;
if (j == bad[i]) {
g[b].push_back({a, c, d});
continue;
}
g[a].push_back({b, c, d});
}
vector<pair<ll, ll>> v1 = dxs(color[0]), v2 = dxs(color[n - 1]);
answer = min(answer, v1[color[n - 1]].first + v2[color[0]].first + r[i].d);
}
if (answer >= INF) {
cout << -1 << endl;
return 0;
}
cout << answer;
}
| # | 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... |