Search for a command to run...
Progressive hints first, then the full explanation and implementation when you're ready to cash out.
Review status
AI-generated and still unreviewed. Double-check the details before internalizing them.
Hints
Open only as much as you need to keep the solve alive.
There are exactly possible pairs with . Since that is also and no pair repeats, every pair occurs. Start with the diagonal restriction : what does it tell you about the sign of ?
The diagonal splits indices into two groups: forces , while forces . Two indices from the first group can only have a type- restriction; two from the second group can only have type . Any other same-group restriction is an immediate contradiction.
For a cross-group pair, let be non-negative and be negative, and write and . Then . Thus type means , while type means .
Encode each cross-group comparison as an edge: use for type , and for type . We want magnitudes to increase along edges. If this graph is a DAG, a topological order lets you assign distinct magnitudes .
A directed cycle cannot be rescued by equality: the graph is bipartite, so a cycle alternates between negative and non-negative vertices. Every edge from the non-negative side to the negative side represents a strict inequality, so chaining one lap gives . Therefore feasibility is exactly: all same-sign pairs have the forced type, and the cross-group graph is acyclic. Topologically order it and give each vertex its order position as magnitude, with the sign fixed by its diagonal.
The intimidating pile of inequalities is really just an ordering problem wearing a fake mustache.
There are exactly
pairs satisfying . The input contains exactly that many restrictions, and no pair occurs twice. Therefore every possible pair occurs exactly once, including every diagonal pair .
Let denote the restriction type for .
For , the constrained sum is :
So the indices are split into a non-negative group and a negative group .
This immediately settles pairs whose endpoints are in the same group:
If either rule is violated, the answer is NO. Otherwise, same-group pairs impose nothing else.
Consider and . Define positive-side magnitudes
Here and , and
Therefore:
| Restriction | Required comparison | Directed edge | |---|---:|---:| | | | | | | | |
Build a directed graph using exactly these edges for all cross-group pairs. Intuitively, an edge points from the endpoint that may receive the smaller magnitude toward the endpoint that must receive the larger one.
The first relation is non-strict, but we will deliberately satisfy it strictly. That is allowed: certainly implies . The only question is whether making every edge strict could create a fake impossibility. It does not.
Every graph edge joins and , so the graph is bipartite.
Suppose it contains a directed cycle. While following that cycle:
A cycle alternates between the two groups, so it contains at least one edge of the second kind. Chaining all comparisons around the cycle gives
which implies . That is impossible. Hence any feasible instance must produce a DAG.
Now suppose the graph is acyclic. Take any topological order
and assign
Every edge goes forward in the topological order, so . Consequently:
Finally restore the signs fixed by the diagonal:
All assigned magnitudes are positive. That is fine even though the first group merely permits zero; nobody said we had to use it.
NO.NO. Otherwise print the constructed array.Lemma 1. A same-group pair is satisfiable exactly when its restriction has the forced type checked by the algorithm.
Proof. Two non-negative values always have a non-negative sum, so only type works. Two negative values always have a negative sum, so only type works. These conclusions do not depend on the chosen magnitudes.
Lemma 2. If the cross-group graph has a directed cycle, no valid array exists.
Proof. The cycle alternates between and . Its edges encode non-strict magnitude inequalities, while its edges encode strict ones. There is at least one strict edge, so chaining the inequalities around the cycle states that one magnitude is strictly smaller than itself, a contradiction.
Lemma 3. If all same-group checks pass and the cross-group graph is acyclic, the algorithm's array satisfies every restriction.
Proof. Topological ranks strictly increase along every edge. Thus every type- cross pair has negative-side magnitude smaller than positive-side magnitude, making its sum non-negative, and every type- cross pair has positive-side magnitude smaller, making its sum negative. Lemma 1 handles all same-group pairs. The assigned signs also satisfy every diagonal restriction. Since every possible pair appears in the input, all restrictions are covered.
Theorem. The algorithm prints YES with a valid array if and only if such an array exists.
Proof. If it prints YES, validity follows from Lemma 3. If it prints NO, either a same-group restriction is impossible by Lemma 1, or topological sorting found a cycle, which is impossible by Lemma 2. Thus it rejects exactly the infeasible instances.
The matrix scan and graph construction take time. Topological sorting takes time, and the matrix plus graph use memory. The output values satisfy , comfortably below .
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
int main() {
setIO();
int t;
cin >> t;
while (t--) {
int n, m;
cin >> n >> m;
vector<vector<int>> rule(n, vector<int>(n));
for (int k = 0; k < m; ++k) {
int o, i, j;
cin >> o >> i >> j;
--i;
--j;
rule[i][j] = rule[j][i] = o;
}
vector<vector<int>> graph(n);
vector<int> indegree(n);
bool ok = true;
for (int i = 0; i < n; ++i) {
for (int j = i + 1; j < n; ++j) {
if (rule[i][i] == rule[j][j]) {
if (rule[i][j] != rule[i][i]) ok = false;
continue;
}
int p = (rule[i][i] == 1 ? i : j);
int neg = (rule[i][i] == 2 ? i : j);
if (rule[i][j] == 1) {
graph[neg].push_back(p);
++indegree[p];
} else {
graph[p].push_back(neg);
++indegree[neg];
}
}
}
if (!ok) {
cout << "NO\n";
continue;
}
queue<int> q;
for (int i = 0; i < n; ++i) {
if (indegree[i] == 0) q.push(i);
}
vector<int> answer(n);
int used = 0;
while (!q.empty()) {
int u = q.front();
q.pop();
int magnitude = ++used;
answer[u] = (rule[u][u] == 1 ? magnitude : -magnitude);
for (int v : graph[u]) {
if (--indegree[v] == 0) q.push(v);
}
}
if (used != n) {
cout << "NO\n";
continue;
}
cout << "YES\n";
for (int i = 0; i < n; ++i) {
cout << answer[i] << (i + 1 == n ? '\n' : ' ');
}
}
return 0;
}#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
int main() {
setIO();
int t;
cin >> t;
while (t--) {
int n, m;
cin >> n >> m;
vector<vector<int>> rule(n, vector<int>(n));
for (int k = 0; k < m; ++k) {
int o, i, j;
cin >> o >> i >> j;
--i;
--j;
rule[i][j] = rule[j][i] = o;
}
vector<vector<int>> graph(n);
vector<int> indegree(n);
bool ok = true;
for (int i = 0; i < n; ++i) {
for (int j = i + 1; j < n; ++j) {
if (rule[i][i] == rule[j][j]) {
if (rule[i][j] != rule[i][i]) ok = false;
continue;
}
int p = (rule[i][i] == 1 ? i : j);
int neg = (rule[i][i] == 2 ? i : j);
if (rule[i][j] == 1) {
graph[neg].push_back(p);
++indegree[p];
} else {
graph[p].push_back(neg);
++indegree[neg];
}
}
}
if (!ok) {
cout << "NO\n";
continue;
}
queue<int> q;
for (int i = 0; i < n; ++i) {
if (indegree[i] == 0) q.push(i);
}
vector<int> answer(n);
int used = 0;
while (!q.empty()) {
int u = q.front();
q.pop();
int magnitude = ++used;
answer[u] = (rule[u][u] == 1 ? magnitude : -magnitude);
for (int v : graph[u]) {
if (--indegree[v] == 0) q.push(v);
}
}
if (used != n) {
cout << "NO\n";
continue;
}
cout << "YES\n";
for (int i = 0; i < n; ++i) {
cout << answer[i] << (i + 1 == n ? '\n' : ' ');
}
}
return 0;
}