답안 #590372

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
590372 2022-07-05T21:43:34 Z Sam_a17 Shortcut (IOI16_shortcut) C++14
0 / 100
1 ms 468 KB
#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
// #include "shortcut_c.h"
#include <cstdio>
using namespace std;
#define ll long long

const int N = 2e3 + 10;
long long dist[N][N];
const ll inf = 1e16;
long long maxLeft[N], maxRight[N], kox[N];
long long maxLeftDiam[N], maxRightDiam[N];
multiset<pair<ll, long long>> adj[N];
int ni;

pair<long long, long long> djik(int node) {
  vector<bool> used(ni + 1);
  vector<long long> dist(ni + 1, inf);
  priority_queue<pair<ll, ll>, vector<pair<ll, ll>> , greater<pair<ll, ll>> > q;
  dist[node] = 0;
  q.push({0, node});
 
  while(!q.empty()) {
    auto u = q.top();
    q.pop();

    if(used[u.second]) {
      continue;
    }
    used[u.second] = true;

    for(auto i: adj[u.second]) {
      if(dist[i.first] > dist[u.second] + i.second) {
        dist[i.first] = dist[u.second] + i.second;
        q.push({dist[i.first], i.first});
      }
    }
  }

  pair<ll, ll> answ = {-1, -1};

  for(int i = 0; i < ni; i++) {
    if(dist[i] == inf) {
      assert(false);
    }

    if(dist[i] > answ.first) {
      answ = {dist[i], i};
    }
  }

  return answ;
}

void djik2(int node) {
  vector<bool> used(ni + 1);
  priority_queue<pair<ll, ll>, vector<pair<ll, ll>> , greater<pair<ll, ll>> > q;
  for(int i = 0; i < ni; i++) {
    dist[node][i] = inf;
  }
  dist[node][node] = 0;
  q.push({0, node});
 
  while(!q.empty()) {
    auto u = q.top();
    q.pop();

    if(used[u.second]) {
      continue;
    }
    used[u.second] = true;

    for(auto i: adj[u.second]) {
      if(dist[node][i.first] > dist[node][u.second] + i.second) {
        dist[node][i.first] = dist[node][u.second] + i.second;
        q.push({dist[node][i.first], i.first});
      }
    }
  }
}

void djik3(int node, vector<ll>& dist) {
  vector<bool> used(ni + 1);
  // vector<long long> dist(ni + 1, inf);
  priority_queue<pair<ll, ll>, vector<pair<ll, ll>> , greater<pair<ll, ll>> > q;
  dist[node] = 0;
  q.push({0, node});
 
  while(!q.empty()) {
    auto u = q.top();
    q.pop();

    if(used[u.second]) {
      continue;
    }
    used[u.second] = true;

    for(auto i: adj[u.second]) {
      if(dist[i.first] > dist[u.second] + i.second) {
        dist[i.first] = dist[u.second] + i.second;
        q.push({dist[i.first], i.first});
      }
    }
  }
}

long long find_shortcut(int n, std::vector<int> l, std::vector<int> d, int c) {
  maxLeft[0] = d[0];
  for(int i = 1; i < n; i++) {
    maxLeft[i] = max(maxLeft[i - 1] + (long long)l[i - 1], (long long)d[i]); 
  }

  maxRight[n - 1] = d[n - 1];
  for(int i = n - 2; i >= 0; i--) {
    maxRight[i] = max(maxRight[i + 1] + (long long)l[i], (long long)d[i]);
  }

  maxLeftDiam[0] = maxLeft[0];
  for(int i = 1; i < n; i++) {
    maxLeftDiam[i] = max(maxLeftDiam[i - 1], maxLeft[i - 1] + (long long)l[i - 1] + (long long)d[i]);
  }

  maxRightDiam[n - 1] = maxRight[n - 1];
  for(int i = n - 2; i >= 0; i--) {
    maxRightDiam[i] = max(maxRightDiam[i + 1], maxRight[i + 1] + (long long)l[i] + (long long)d[i]);
  }

  ni = n;

  if(d[0]) {
    kox[0] = ni;
    adj[0].insert({ni, d[0]});
    adj[ni++].insert({0, d[0]});
  }

  for(int i = 1; i < n; i++) {

    adj[i - 1].insert({i, l[i - 1]});
    adj[i].insert({i - 1, l[i - 1]});

    if(d[i]) {
      kox[i] = ni;
      adj[i].insert({ni, d[i]});
      adj[ni++].insert({i, d[i]});
    }
  }

  for(int i = 0; i < ni; i++) {
    if(!kox[i]) kox[i] = i;
    djik2(i);
  }

  long long minDiametr = djik(djik(0).second).first;

  for(int i = 0; i < n; i++) {
    long long s = 0;
    for(int j = i + 1; j < n; j++) {
      s += l[j - 1];

      if(s <= c) {
        continue;
      }

      adj[i].insert({j, (long long)c});
      adj[j].insert({i, (long long)c});

      vector<long long> d1(ni + 1, inf), d2(ni + 1, inf);

      djik3(i, d1);
      djik3(j, d2);
      
      long long maxi = max({maxLeftDiam[i], maxRightDiam[j], maxLeft[i] + maxRight[j] + c});
      
      for(int k = i; k <= j; k++) {
          for(int g = i; g <= j; g++) {
            if(min(d1[kox[g]] + d1[kox[k]], d2[kox[g]] + d2[kox[k]]) < dist[kox[k]][kox[g]]) {
              maxi = max(maxi, min(d1[kox[g]] + d1[kox[k]], d2[kox[g]] + d2[kox[k]]));
            } else {
              maxi = max(maxi, dist[kox[k]][kox[g]]);
            }
          }

          // if(i == 0 && j == 3 && kox[k] == 5) {
            // cout << "------" << endl;
            // cout << min(d1[] + d1[kox[k]], d2[g] + d2[kox[k]]) << endl;
            // cout << maxi << endl;    
            // cout << "-------" << endl;        
          // }
          // kox[k] -> i
          // kox[k] -> j

          if(min(d1[i] + d1[kox[k]], d2[i] + d2[kox[k]]) < dist[kox[k]][i]) {
            maxi = max(maxi, min(d1[i] + d1[kox[k]], d2[i] + d2[kox[k]]) + maxLeft[i]);
          } else {
            maxi = max(maxi, dist[kox[k]][i] + maxLeft[i]);
          }

          if(min(d1[j] + d1[kox[k]], d2[j] + d2[kox[k]]) < dist[kox[k]][j]) {
            maxi = max(maxi, min(d1[j] + d1[kox[k]], d2[j] + d2[kox[k]]) + maxRight[j]);
          } else {
            maxi = max(maxi, dist[kox[k]][j] + maxRight[j]);
          }
        
      }

      // cout << i << " " << j << endl;
      // cout << maxi << endl;

      minDiametr = min(maxi, minDiametr);

      adj[i].erase(adj[i].find(make_pair(j, (ll)c)));
      adj[j].erase(adj[j].find(make_pair(i, (ll)c)));
    }
  }

  return minDiametr;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 340 KB n = 4, 80 is a correct answer
2 Correct 1 ms 468 KB n = 9, 110 is a correct answer
3 Correct 1 ms 340 KB n = 4, 21 is a correct answer
4 Correct 1 ms 340 KB n = 3, 4 is a correct answer
5 Incorrect 1 ms 396 KB n = 2, incorrect answer: jury 62 vs contestant 71
6 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 340 KB n = 4, 80 is a correct answer
2 Correct 1 ms 468 KB n = 9, 110 is a correct answer
3 Correct 1 ms 340 KB n = 4, 21 is a correct answer
4 Correct 1 ms 340 KB n = 3, 4 is a correct answer
5 Incorrect 1 ms 396 KB n = 2, incorrect answer: jury 62 vs contestant 71
6 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 340 KB n = 4, 80 is a correct answer
2 Correct 1 ms 468 KB n = 9, 110 is a correct answer
3 Correct 1 ms 340 KB n = 4, 21 is a correct answer
4 Correct 1 ms 340 KB n = 3, 4 is a correct answer
5 Incorrect 1 ms 396 KB n = 2, incorrect answer: jury 62 vs contestant 71
6 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 340 KB n = 4, 80 is a correct answer
2 Correct 1 ms 468 KB n = 9, 110 is a correct answer
3 Correct 1 ms 340 KB n = 4, 21 is a correct answer
4 Correct 1 ms 340 KB n = 3, 4 is a correct answer
5 Incorrect 1 ms 396 KB n = 2, incorrect answer: jury 62 vs contestant 71
6 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 340 KB n = 4, 80 is a correct answer
2 Correct 1 ms 468 KB n = 9, 110 is a correct answer
3 Correct 1 ms 340 KB n = 4, 21 is a correct answer
4 Correct 1 ms 340 KB n = 3, 4 is a correct answer
5 Incorrect 1 ms 396 KB n = 2, incorrect answer: jury 62 vs contestant 71
6 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 340 KB n = 4, 80 is a correct answer
2 Correct 1 ms 468 KB n = 9, 110 is a correct answer
3 Correct 1 ms 340 KB n = 4, 21 is a correct answer
4 Correct 1 ms 340 KB n = 3, 4 is a correct answer
5 Incorrect 1 ms 396 KB n = 2, incorrect answer: jury 62 vs contestant 71
6 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 340 KB n = 4, 80 is a correct answer
2 Correct 1 ms 468 KB n = 9, 110 is a correct answer
3 Correct 1 ms 340 KB n = 4, 21 is a correct answer
4 Correct 1 ms 340 KB n = 3, 4 is a correct answer
5 Incorrect 1 ms 396 KB n = 2, incorrect answer: jury 62 vs contestant 71
6 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 340 KB n = 4, 80 is a correct answer
2 Correct 1 ms 468 KB n = 9, 110 is a correct answer
3 Correct 1 ms 340 KB n = 4, 21 is a correct answer
4 Correct 1 ms 340 KB n = 3, 4 is a correct answer
5 Incorrect 1 ms 396 KB n = 2, incorrect answer: jury 62 vs contestant 71
6 Halted 0 ms 0 KB -