#include "shortcut.h"
#include <bits/stdc++.h>
using ll = long long;
std::vector<ll> distBefore;
ll mainLineDist(int a, int b)
{
if (a > b)
std::swap(a, b);
if (a == b)
return 0;
return distBefore[b - 1] - ((a == 0) ? 0 : distBefore[a - 1]);
}
struct Edge
{
int length;
int other;
};
struct Node
{
int mlIndex;
std::vector<Edge> edges;
};
std::vector<Node> nodes;
ll halfLoopLen;
int expA, expB, expLen;
std::vector<int> mlNodes;
const ll BIG = INT64_MAX;
bool OnLoop(const Node& n)
{
return n.mlIndex >= expA && n.mlIndex <= expB;
}
std::pair<int, ll> FindFurthestNode(int n, int pn, ll loopDist)
{
std::pair<int, ll> ans(n, 0);
//std::pair<int, ll> minLoop(-1, BIG);
for (const Edge& edge : nodes[n].edges)
{
if (edge.other == pn)
continue;
if (OnLoop(nodes[n]) && OnLoop(nodes[edge.other]))
{
ll nextLoopDist = loopDist + edge.length;
if (nextLoopDist > halfLoopLen)
continue;
auto pAns = FindFurthestNode(edge.other, n, nextLoopDist);
pAns.second += edge.length;
if (pAns.second > ans.second)
ans = pAns;
}
else
{
auto pAns = FindFurthestNode(edge.other, n, loopDist);
pAns.second += edge.length;
if (pAns.second > ans.second)
ans = pAns;
}
}
ll expNextLoopLen = loopDist + expLen;
if (nodes[n].mlIndex == expA && nodes[pn].mlIndex != expB && expNextLoopLen <= halfLoopLen)
{
auto pAns = FindFurthestNode(mlNodes[expB], n, expNextLoopLen);
pAns.second += expLen;
if (pAns.second > ans.second)
ans = pAns;
}
if (nodes[n].mlIndex == expB && nodes[pn].mlIndex != expA && expNextLoopLen <= halfLoopLen)
{
auto pAns = FindFurthestNode(mlNodes[expA], n, expNextLoopLen);
pAns.second += expLen;
if (pAns.second > ans.second)
ans = pAns;
}
//if (minLoop.first != -1 && minLoop.second > ans.second)
// ans = minLoop;
return ans;
}
long long find_shortcut(int n, std::vector<int> l, std::vector<int> d, int c)
{
distBefore.resize(n - 1);
ll distAcc = 0;
for (int i = 0; i < l.size(); i++)
{
distAcc += l[i];
distBefore[i] = distAcc;
}
expLen = c;
mlNodes.resize(n);
int prevMlNodeI;
for (int i = 0; i < n; i++)
{
int mlNodeI = nodes.size();
nodes.emplace_back();
nodes[mlNodeI].mlIndex = i;
mlNodes[i] = mlNodeI;
if (d[i] != 0)
{
int slNodeI = nodes.size();
nodes.emplace_back();
nodes[slNodeI].mlIndex = -1;
nodes[mlNodeI].edges.push_back(Edge { d[i], slNodeI });
nodes[slNodeI].edges.push_back(Edge { d[i], mlNodeI });
}
if (i != 0)
{
nodes[mlNodeI].edges.push_back(Edge { l[i - 1], prevMlNodeI });
nodes[prevMlNodeI].edges.push_back(Edge { l[i - 1], mlNodeI });
}
prevMlNodeI = mlNodeI;
}
ll ans = INT64_MAX;
for (ll a = 0; a < n; a++)
{
for (ll b = a + 1; b < n; b++)
{
halfLoopLen = (mainLineDist(a, b) + c) / 2;
expA = std::min(a, b);
expB = std::max(a, b);
//std::cout << a << " - " << b << std::endl;
std::pair<int, ll> n1 = FindFurthestNode(0, -1, 0);
std::pair<int, ll> n2 = FindFurthestNode(n1.first, -1, 0);
//std::cout << "\t n1: " << n1.first << ", d=" << n1.second << std::endl;
//std::cout << "\t n2: " << n2.first << ", d=" << n2.second << std::endl;
ans = std::min(ans, n2.second);
/*
ll md = 0;
for (ll u = 0; u < n; u++)
{
for (ll v = u + 1; v < n; v++)
{
ll e = d[u] + d[v];
ll minThis = INT64_MAX;
minThis = std::min(minThis, mainLineDist(u, v) + e);
minThis = std::min(minThis, mainLineDist(u, a) + mainLineDist(v, b) + e + c);
minThis = std::min(minThis, mainLineDist(u, b) + mainLineDist(v, a) + e + c);
md = std::max(md, minThis);
}
}
ans = std::min(ans, md);*/
}
}
return ans;
}
Compilation message
shortcut.cpp: In function 'long long int find_shortcut(int, std::vector<int>, std::vector<int>, int)':
shortcut.cpp:101:23: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
for (int i = 0; i < l.size(); i++)
~~^~~~~~~~~~
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
3 ms |
344 KB |
n = 4, 80 is a correct answer |
2 |
Incorrect |
3 ms |
488 KB |
n = 9, incorrect answer: jury 110 vs contestant 100 |
3 |
Halted |
0 ms |
0 KB |
- |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
3 ms |
344 KB |
n = 4, 80 is a correct answer |
2 |
Incorrect |
3 ms |
488 KB |
n = 9, incorrect answer: jury 110 vs contestant 100 |
3 |
Halted |
0 ms |
0 KB |
- |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
3 ms |
344 KB |
n = 4, 80 is a correct answer |
2 |
Incorrect |
3 ms |
488 KB |
n = 9, incorrect answer: jury 110 vs contestant 100 |
3 |
Halted |
0 ms |
0 KB |
- |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
3 ms |
344 KB |
n = 4, 80 is a correct answer |
2 |
Incorrect |
3 ms |
488 KB |
n = 9, incorrect answer: jury 110 vs contestant 100 |
3 |
Halted |
0 ms |
0 KB |
- |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
3 ms |
344 KB |
n = 4, 80 is a correct answer |
2 |
Incorrect |
3 ms |
488 KB |
n = 9, incorrect answer: jury 110 vs contestant 100 |
3 |
Halted |
0 ms |
0 KB |
- |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
3 ms |
344 KB |
n = 4, 80 is a correct answer |
2 |
Incorrect |
3 ms |
488 KB |
n = 9, incorrect answer: jury 110 vs contestant 100 |
3 |
Halted |
0 ms |
0 KB |
- |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
3 ms |
344 KB |
n = 4, 80 is a correct answer |
2 |
Incorrect |
3 ms |
488 KB |
n = 9, incorrect answer: jury 110 vs contestant 100 |
3 |
Halted |
0 ms |
0 KB |
- |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
3 ms |
344 KB |
n = 4, 80 is a correct answer |
2 |
Incorrect |
3 ms |
488 KB |
n = 9, incorrect answer: jury 110 vs contestant 100 |
3 |
Halted |
0 ms |
0 KB |
- |