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 "closing.h"
#ifdef LOCAL
#include "Debug.h"
#else
#define debug(...) 42
#endif
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5;
const long long oo = (1LL << 62) - 10;
int n;
vector<pair<int, int>> a[N];
vector<int> idPath, idTree;
vector<long long> bfs(int s)
{
vector<long long> dist(n, -1);
queue<int> q;
dist[s] = 0;
q.push(s);
while (!empty(q))
{
int x = q.front();
q.pop();
for (auto [y, w] : a[x])
if (dist[y] < 0)
{
dist[y] = dist[x] + w;
q.push(y);
}
}
return dist;
}
int isLinear()
{
for (int i = 0; i + 1 < n; i++)
{
int isGood = 0;
for (auto [j, _] : a[i])
if (j == i + 1)
isGood = 1;
if (!isGood)
return 0;
}
return 1;
}
int solveLinear(int n, int A, int B, long long budget, vector<long long> distA, vector<long long> distB)
{
vector<long long> sumA(n), sumB(n), sumAB(n);
for (int i = A; i <= B; i++)
{
sumA[i] = distA[i];
sumAB[i] = max(distA[i], distB[i]);
if (i)
{
sumA[i] += sumA[i - 1];
sumAB[i] += sumAB[i - 1];
}
}
for (int i = B - 1; i >= A; i--)
sumB[i] = sumB[i + 1] + distB[i];
vector<pair<long long, int>> ext;
for (int i = 0; i < n; i++)
if (i < A) ext.push_back({distA[i], i});
else if (i > B) ext.push_back({distB[i], i});
vector<long long> costFor(n, oo);
costFor[0] = 0;
sort(begin(ext), end(ext));
for (int i = 0; i < size(ext); i++)
costFor[i + 1] = costFor[i] + ext[i].first;
int ans = 0, distAB = distA[B];
for (int l = A; l <= B; l++)
for (int r = A; r <= B; r++)
{
long long cost = 0;
int curAns = l - A + 1 + B - r + 1;
if (l < r) cost = sumA[l] + sumB[r];
else
{
cost = sumAB[l];
if (r)
{
cost -= sumAB[r - 1];
cost += sumA[r - 1];
}
if (l + 1 < n)
cost += sumB[l + 1];
}
if (cost > budget)
continue;
if (l < B && r > A)
{
int u = upper_bound(begin(costFor), end(costFor), budget - cost) - begin(costFor);
curAns += u - 1;
}
else
{
long long rem = budget - cost;
int both = 0;
for (int i = 0; i < size(ext); i++)
{
auto [extCost, id] = ext[i];
while (both && extCost > distAB)
{
rem -= distAB;
if (rem < 0)
break;
curAns++;
both--;
}
rem -= extCost;
if (rem < 0)
break;
curAns++;
if (id < A && r == A) both++;
else if (id > B && l == B) both++;
}
if (rem >= 0)
curAns += min(1LL * both, rem / distAB);
}
ans = max(ans, curAns);
}
return ans;
}
int findPath(int x, int goal, int par, vector<int> &path)
{
path.push_back(x);
if (x == goal)
return 1;
for (auto [y, _] : a[x])
if (y != par)
{
if (findPath(y, goal, x, path))
return 1;
}
path.pop_back();
return 0;
}
void dfs(int x)
{
for (auto [y, _] : a[x])
if (idTree[y] < 0)
{
idTree[y] = idTree[x];
dfs(y);
}
}
int max_score(int N, int A, int B, long long budget, vector<int> U, vector<int> V, vector<int> W)
{
n = N;
for (int i = 0; i < n; i++)
a[i].clear();
for (int i = 0; i < size(U); i++)
{
a[U[i]].push_back({V[i], W[i]});
a[V[i]].push_back({U[i], W[i]});
}
auto distA = bfs(A);
auto distB = bfs(B);
auto distAB = distA[B];
if (distAB > budget * 2)
{
vector<long long> allDists = distA;
for (auto d : distB)
allDists.push_back(d);
sort(begin(allDists), end(allDists));
int ans = 0;
for (auto d : allDists)
if (d <= budget)
{
ans++;
budget -= d;
}
return ans;
}
if (isLinear())
return solveLinear(n, A, B, budget, distA, distB);
// O(n^3)
vector<int> path;
findPath(A, B, -1, path);
idPath.assign(n, -1);
idTree.assign(n, -1);
int len = size(path);
for (int i = 0; i < len; i++)
idPath[path[i]] = idTree[path[i]] = i;
for (int x : path)
dfs(x);
int ans = 0;
vector<long long> f(n * 2 + 1, oo);
for (int l = 0; l < len; l++)
for (int r = 0; r < len; r++)
{
long long curCost = 0;
int curAns = 0;
int cnt = 0;
f[0] = 0;
auto update = [&](long long c1, long long c2)
{
if (c1 > c2)
swap(c1, c2);
for (int i = cnt; i >= 0; i--)
{
f[i + 1] = min(f[i + 1], f[i] + c1);
if (c2 != oo)
f[i + 2] = min(f[i + 2], f[i] + c2);
}
cnt += c2 != oo ? 2 : 1;
};
for (int i = 0; i < n; i++)
{
if (idTree[i] > l && idTree[i] < r)
continue;
if (idTree[i] < r) // A
{
if (idPath[i] < 0) update(distA[i], oo);
else curCost += distA[i], curAns++;
}
else if (idTree[i] > l) // B
{
if (idPath[i] < 0) update(distB[i], oo);
else curCost += distB[i], curAns++;
}
else // AB
{
if (idPath[i] < 0) update(distA[i], distB[i]);
else curCost += max(distA[i], distB[i]), curAns += 2;
}
}
for (int i = 0; i <= cnt; i++)
{
if (curCost + f[i] <= budget)
ans = max(ans, curAns + i);
f[i] = oo;
}
}
return ans;
}
Compilation message (stderr)
closing.cpp: In function 'int solveLinear(int, int, int, long long int, std::vector<long long int>, std::vector<long long int>)':
closing.cpp:74:21: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<long long int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
74 | for (int i = 0; i < size(ext); i++)
| ~~^~~~~~~~~~~
closing.cpp:108:27: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<long long int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
108 | for (int i = 0; i < size(ext); i++)
| ~~^~~~~~~~~~~
closing.cpp: In function 'int max_score(int, int, int, long long int, std::vector<int>, std::vector<int>, std::vector<int>)':
closing.cpp:168:21: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
168 | for (int i = 0; i < size(U); i++)
| ~~^~~~~~~~~
# | 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... |
# | 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... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |