Give solution in cpp. There are n variables; let...
Creado el: 23 de junio de 2025
Creado el: 23 de junio de 2025
Give solution in cpp.
There are n
variables; let's denote the value of the i
-th variable as ai
.
There are also m
operations which will be applied to these variables; the i
-th operation is described by three integers xi,yi,zi
. When the i
-th operation is applied, the variable xi
gets assigned the following value: min(axi,ayi+zi)
.
Every operation will be applied exactly once, but their order is not fixed; they can be applied in any order.
Let's call a sequence of initial variable values a1,a2,…,an
stable, if no matter in which order we apply operations, the resulting values will be the same. If the resulting value of the i
-th variable depends on the order of operations, then the sequence of initial variable values is called i
-unstable.
You have to process q
queries. In each query, you will be given initial values a1,a2,…,an
and an integer k
; before applying the operations, you can at most k
times choose a variable and decrease it by 1
. For every variable i
, you have to independently determine if it is possible to transform the given values into an i
-unstable sequence.
Input
The first line contains two integers n
and m
(2≤n≤500
; 1≤m≤4⋅105
) — the number of variables and operations, respectively.
Then, m
lines follow. The i
-th of them contains three integers xi,yi,zi
(1≤xi,yi≤n
; xi≠yi
; 0≤zi≤105
) — the description of the i
-th operation.
The next line contains one integer q
(1≤q≤1000
) — the number of queries.
Each query consists of two lines:
the first line contains one integer k
(0≤k≤109
) — the maximum number of times you can choose a variable and decrease it by 1
;
the second line contains n
integers a1,a2,…,an
(0≤ai≤109
) — the initial values of the variables.
Output
For each query, print a string of n
zeroes and/or ones. The i
-th character should be 1 if it is possible to obtain an i
-unstable sequence, or 0 otherwise.
Examples
InputCopy
4 5
2 1 10
3 2 5
1 4 8
1 2 6
3 1 17
3
0
20 0 15 5
10
20 0 15 5
30
20 0 15 5
OutputCopy
0000
0000
0110
InputCopy
3 5
1 2 100
1 2 10
1 3 5
1 2 100
3 2 5
1
1000000000
0 0 0
OutputCopy
000
InputCopy
3 4
2 3 5
1 2 0
3 1 4
1 3 4
10
5
7 5 3
2
5 7 0
1
1 1 1
5
3 0 1
0
5 3 5
5
6 0 4
5
1 5 6
1
7 7 2
1
1 6 6
4
7 7 2
OutputCopy
000
000
000
001
000
001
001
000
000
000
Note
Consider the first example. If the initial variable values are [20,0,15,5]
, the resulting values will be [6,0,5,5]
with any order of operations. Decreasing the variables 10
times is not enough. However, if we can apply no more than 30
changes, we can decrease the 1
-st variable by 2
, and the 4
-th variable by 25
, we get initial values equal to [18,0,15,−20]
, and this sequence is 2
-unstable and 3
-unstable:
if you apply the operations in the order they are given, you will get [−12,0,5,−20]
;
however, if you apply the operations in order [3,2,4,1,5]
, you will get [−12,−2,5,−20]
;
and if you apply the operations in order [3,4,5,1,2]
, you will get [−12,−2,3,−20]
.
Solution outline
We model every operation
xi ← min( axi , ayi + zi )
as a directed edge
yi → xi (cost = zi)
Because zi ≥ 0
, applying an operation can only decrease the value of its
target; values never go up again.
If we run all edges that enter i first, each of them uses the initial value of its start‐vertex, so after those first moves
hi = min( ai , min over edges y→i ( ay + wy,i ) )
No ordering can leave i
larger than that, therefore hi
is the maximum
final value of i
.
(store hi
as upper[i]
in the code).
To make i
as small as possible we pick a path of length ≥ 2
s → … → t → i
textcost = dist[s][i] (sum of the edge costs) produced value = as + dist[s][i]
Run every edge on the path from s to t first – that drives
t
down – and run the last edge t → i
at the very end; then i
finishes with that produced value.
Taking the shortest such path gives
lo = min over s≠i, path length≥2 ( as + dist[s][i] )
(we obtain every dist[·][·] once in advance with Floyd-Warshall).
i
is unstable iff two different orders give two different results,
i.e. lo < hi
.
Because you may lower some starting values before executing anything,
let us try to push lo
below hi
by decreasing a single source
vertex s
.
We never touch
i
itself – that would also lower hi
;hi
– that would lower hi
by exactly the same amount.For any other s
need(s,i) = max( 0 , as + dist[s][i] − hi + 1 )
units have to be subtracted from as
.
The smallest of those (need[i]
) is the total number of unit
decrements that turns i
into an i-unstable variable.
i
is answer 1 in a query with budget k
iff need[i] ≤ k
, otherwise 0.
w[y][x]
– smallest weight of a direct edge y→x
(∞ if none)dist
– all–pairs shortest paths on that graphn ≤ 500
→ 125 million relaxations, fine)O(n²)
memory.q ≤ 1000
, n = 500
)ai
, k
hi
← ai
hi
← min( hi , ay + w[y][i] )
for all y
i
s
s = i
dist[s][i] = ∞
s
if it owns a direct edge s→i
and as + w[s][i] = hi
need = max(0, as + dist[s][i] − hi + 1)
1
if that minimum ≤ k
, else 0
Two dense n²
scans → about 0.5 million operations per query, easily
fast enough.
hi
is attainable: run every in-edge of i
first, then anything else.
No later step can increase i
, hence it never exceeds hi
.
lo
is attainable: take the shortest path
s → … → t → i
(length ≥ 2).
Execute all edges up to t
first, then the rest of the graph, finally
edge t→i
. At that moment t
already has its minimal value, so i
receives as + dist[s][i]
.
Need formula: decreasing a source s
that is not the sole direct
originator of hi
changes lo
by exactly the same amount while leaving
hi
unchanged; the formula is the minimal positive amount that makes
lo < hi
.
Thus i
is unstable iff lo < hi
, and the algorithm finds the least
total decrements that achieve that, proving both soundness and
completeness.
cpp#include <bits/stdc++.h> using namespace std; using int64 = long long; const int64 INF = (int64)4e18; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n, m; if (!(cin >> n >> m)) return 0; vector<vector<int64>> w(n, vector<int64>(n, INF)); // direct edge vector<vector<int64>> dist(n, vector<int64>(n, INF)); // shortest path for (int i = 0; i < n; ++i) dist[i][i] = 0; for (int i = 0; i < m; ++i) { int x, y; int z; cin >> x >> y >> z; --x; --y; // 0-based if (z < w[y][x]) { // y → x w[y][x] = z; dist[y][x] = z; } } /* Floyd-Warshall */ for (int k = 0; k < n; ++k) for (int i = 0; i < n; ++i) { if (dist[i][k] == INF) continue; for (int j = 0; j < n; ++j) { if (dist[k][j] == INF) continue; auto nd = dist[i][k] + dist[k][j]; if (nd < dist[i][j]) dist[i][j] = nd; } } int q; cin >> q; vector<int64> a(n), upper(n); string answer; while (q--) { int64 k; cin >> k; for (int i = 0; i < n; ++i) cin >> a[i]; /* 1. compute hi = upper[i] */ for (int i = 0; i < n; ++i) upper[i] = a[i]; for (int y = 0; y < n; ++y) { const int64 ay = a[y]; for (int x = 0; x < n; ++x) if (w[y][x] != INF) { int64 cand = ay + w[y][x]; if (cand < upper[x]) upper[x] = cand; } } answer.clear(); answer.reserve(n); for (int i = 0; i < n; ++i) { int64 need = INF; for (int s = 0; s < n; ++s) { if (s == i) continue; int64 d = dist[s][i]; if (d == INF) continue; /* if s→i exists and uses hi, skip (path length would be 1) */ if (w[s][i] != INF && a[s] + w[s][i] == upper[i]) continue; int64 delta = a[s] + d - upper[i] + 1; if (delta < 0) delta = 0; if (delta < need) need = delta; } answer.push_back( (need <= k) ? '1' : '0' ); } cout << answer << '\n'; } return 0; }
The program follows exactly the reasoning above:
pre-computation
– w
for single-edge costs, dist
for all-pairs shortest paths.
per query
– compute every hi
in O(n²)
,
– find the minimal required decrements for each variable in O(n²)
,
– output the 0/1 string.
Time-complexity
textpre-processing: O(n³) ≤ 125 ·10⁶ operations each query: O(n²) ≈ 5 ·10⁵ operations
Memory-usage
textdist, w : n² · 8 bytes ≈ 2 MB aux arrays: negligible
Well within the limits (n ≤ 500
, m ≤ 4·10⁵
, q ≤ 1000
).