Submission #297209

#TimeUsernameProblemLanguageResultExecution timeMemory
297209BruteforcemanOlympic Bus (JOI20_ho_t4)C++11
16 / 100
899 ms5456 KiB
#include <bits/stdc++.h>
using namespace std;
const int maxn = 205;
const int maxm = 5e4 + 10;
const long long inf = 1e15;
bool del[maxm];
int l[maxm], r[maxm], w[maxm], c[maxm];
int n, m;
vector <int> g[maxn];
bool imp[maxm];

vector <long long> shortest_path(int src, bool rev = false, bool mark = false) {
  vector <long long> d (n, inf);
  vector <bool> done (n, false);
  d[src] = 0;
  while(true) {
    int x = -1;
    for(int i = 0; i < n; i++) {
      if(done[i]) continue;
      if(x == -1 || d[x] > d[i]) {
        x = i;
      }
    }
    if(x == -1) break;
    done[x] = true;
    for(int e : g[x]) {
      if(del[e]) continue;
      if(rev && l[e] == x) continue;
      if(!rev && r[e] == x) continue;
      int y = l[e] ^ r[e] ^ x;
      if(d[y] > d[x] + w[e]) {
        d[y] = d[x] + w[e];
      }
    }
  }
  if(mark) {
    vector <int> par (n, -1);
    for(int x = 0; x < n; x++) {
      for(int e : g[x]) {
        if(del[e]) continue;
        if(rev && l[e] == x) continue;
        if(!rev && r[e] == x) continue;
        int y = l[e] ^ r[e] ^ x;
        if(d[y] == d[x] + w[e]) {
          par[y] = e;
        }
      }
    }
    for(int i = 0; i < n; i++) if(par[i] != -1) imp[par[i]] = true;
  }
  return d;
}
int main() {
  cin >> n >> m;
  for(int i = 0; i < m; i++) {
    cin >> l[i] >> r[i] >> w[i] >> c[i];
    l[i] -= 1;
    r[i] -= 1;
    g[l[i]].push_back(i);
    g[r[i]].push_back(i);
  }
  
  vector <long long> srcPath (m, inf), desPath(m, inf);
  vector <long long> leftSrc (m, inf), srcRight (m, inf);
  vector <long long> leftDes (m, inf), desRight (m, inf);
  
  fill(imp, imp + m, false);
  auto fromSrc = shortest_path(0, false, true);
  for(int i = 0; i < m; i++) {
    if(imp[i]) {
      del[i] = true;
      auto u = shortest_path(0); 
      srcPath[i] = u[n - 1];
      srcRight[i] = u[r[i]];
      del[i] = false;
    } else {
      srcPath[i] = fromSrc[n - 1];
      srcRight[i] = fromSrc[r[i]]; 
    }
  }

  fill(imp, imp + m, false);
  auto fromDes = shortest_path(n - 1, false, true);
  for(int i = 0; i < m; i++) {
    if(imp[i]) {
      del[i] = true;
      auto v = shortest_path(n - 1);
      desRight[i] = v[r[i]];
      desPath[i] = v[0]; 
      del[i] = false;
    } else {
      desRight[i] = fromDes[r[i]];
      desPath[i] = fromDes[0];
    }
  }
  fill(imp, imp + m, false);
  auto toSrc = shortest_path(0, true, true);
  for(int i = 0; i < m; i++) {
    if(imp[i]) {
      del[i] = true;
      auto u = shortest_path(0, true);
      leftSrc[i] = u[l[i]];
      del[i] = false;
    } else {
      leftSrc[i] = toSrc[l[i]]; 
    }
  }
  fill(imp, imp + m, false);
  auto toDes = shortest_path(n - 1, true, true);
  for(int i = 0; i < m; i++) {
    if(imp[i]) {
      del[i] = true;
      auto v = shortest_path(n - 1, true);
      leftDes[i] = v[l[i]];
      del[i] = false;
    } else {
      leftDes[i] = toDes[l[i]];
    }
  }
  long long ans = fromSrc[n - 1] + fromDes[0];
  for(int i = 0; i < m; i++) {
    long long res = c[i];
    res += min(srcRight[i] + w[i] + leftDes[i], srcPath[i]);
    res += min(desRight[i] + w[i] + leftSrc[i], desPath[i]);
    ans = min(ans, res);
  }
  if(ans >= inf) ans = -1;
  cout << ans << endl;
  return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...