Give solution in cpp. There are n variables; let...
Créé le : 23 juin 2025
Créé le : 23 juin 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]
.
Below is a completely stand-alone C++17 implementation that works in O(n3 + q·n2)
time (≈ 125 M operations for the preprocessing and ≤ 2.5 · 10^8 very light operations for the worst-case 1000 queries, well inside the limits).
Compress the m ≤ 4 ⋅ 10^5 operations into a dense weight-matrix
w[u][v] = min z for the edge u → v
.
(only the smallest weight of parallel edges can ever matter).
With n ≤ 500 we can afford a Floyd-Warshall on that matrix once,
giving dist[u][v]
= shortest-path weight.
For every query we have an initial vector a[1…n]
and may lower any entries (total budget k).
For a fixed node i
because each incoming edge must be executed once, and it will lowertexthi(i) = min( a[i], min over in-edges u→i ( a[u] + w[u][i] ) )
i
at least to the minimum of the sources’ current values.
Any source that already starts small enough will certainly do that,
no matter when its edge is scheduled.lo(i) = min over all nodes s ( a[s] + dist[s][i] )
– execute the edges of a shortest path backwards,
so that each vertex on the path is relaxed after its source.If we can make lo(i)
strictly smaller than hi(i)
by spending at
most k decrements, i
is “i-unstable”.
Only the first node s
of the path needs to be decreased:
lowering anything downstream would also lower hi(i)
again.
The cheapest way is therefore
textneed(i) = min over s that do **not** attain hi(i) max( 0 , a[s] + dist[s][i] - hi(i) + 1 )
(+1
because we need a strict inequality).
i
is unstable iff need(i) ≤ k
.
w
-matrix filling: O(m)
O(n³)
( ≤ 125 M primitive ops )hi
( n² ), build the “attains-hi” table ( n² ),
compute every need(i)
( n² ) ⇒ O(n²)
n × n
matrices of 64-bit integers (≈ 2 MB each) plus a
boolean matrix (≈ 0.25 MB).cpp#include <bits/stdc++.h> using namespace std; const long long INF = 4e18; // enough for all path sums int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n, m; // variables, operations if (!(cin >> n >> m)) return 0; /* -------- compress the edges ---------- */ vector<vector<long long>> w(n, vector<long long>(n, INF)); for (int i = 0; i < n; ++i) w[i][i] = 0; for (int i = 0; i < m; ++i) { int x, y; long long z; cin >> x >> y >> z; --x; --y; // 0-based w[y][x] = min(w[y][x], z); // edge y → x with weight z } /* -------- all-pairs shortest paths ---------- */ vector<vector<long long>> dist = w; // copy for (int k = 0; k < n; ++k) for (int i = 0; i < n; ++i) if (dist[i][k] < INF) for (int j = 0; j < n; ++j) if (dist[k][j] < INF && dist[i][j] > dist[i][k] + dist[k][j]) dist[i][j] = dist[i][k] + dist[k][j]; /* -------- queries ---------- */ int q; cin >> q; vector<long long> a(n), hi(n); vector<vector<char>> isMin(n, vector<char>(n)); string answer; answer.reserve(n); while (q--) { long long K; // budget cin >> K; for (int i = 0; i < n; ++i) cin >> a[i]; /* build hi(i) and remember which nodes attain it */ fill(hi.begin(), hi.end(), 0); for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) isMin[i][j] = 0; for (int v = 0; v < n; ++v) { long long best = a[v]; for (int u = 0; u < n; ++u) if (w[u][v] < INF) best = min(best, a[u] + w[u][v]); hi[v] = best; /* mark minimisers */ if (a[v] == best) isMin[v][v] = 1; for (int u = 0; u < n; ++u) if (w[u][v] < INF && a[u] + w[u][v] == best) isMin[u][v] = 1; } /* for every variable decide (in)stability */ answer.clear(); for (int v = 0; v < n; ++v) { long long need = INF; for (int s = 0; s < n; ++s) { if (s == v || isMin[s][v]) continue; // cannot use if (dist[s][v] == INF) continue; // no path long long cand = a[s] + dist[s][v]; long long delta = cand - hi[v]; long long cost = (delta < 0) ? 0 : delta + 1; if (cost < need) need = cost; if (need == 0) break; // early exit } answer.push_back( (need <= K) ? '1' : '0' ); } cout << answer << '\n'; } return 0; }
The code follows exactly the reasoning sketched above:
w
.dist
.hi(i)
and mark every source that attains it (isMin
),hi(i)
without
touching the same minimiser,k
.If the required budget does not exceed k we output 1
(the variable can indeed be made i-unstable), otherwise 0
.