首先,对于两辆车而言,注定相遇就是相向而驰,注定不相遇就是背道而驰,没有关系的两辆车就是同向的。如果一辆车既向左开,又向右开,那么这种情况一定无解,输出 NO。我们就可以用二分图染色的方法来判断它。然后方向确定了,我们还要考虑位置的问题。我们设第 \(i\) 辆车的方向为右,第 \(j\) 辆车的方向为左。如果这两辆车注定相遇,则第 \(i\) 辆车的初始位置要小于第 \(j\) 辆车的初始位置。如果这两辆车注定不相遇,则第 \(i\) 辆车的初始位置要大于第 \(j\) 辆车的初始位置。在二分图染色的过程中,我们可以对于一种颜色的汽车,将它们设为同一种方向。如果这些汽车的位置依赖关系存在环,则这种情况也一定无解,输出 NO。所以我们就可以进行拓扑排序来判断是否有环,同时为每辆车赋上初始位置。然后输出即可。
下面是代码环节:
#include<bits/stdc++.h>
using namespace std;
struct Node {int op, x, y;
} a[200005];
int n, m, color[200005], ans[200005], num[200005];
bool flag;
queue<int> q;
vector<int> v1[200005];
vector<pair<int, int>> v[200005];
void dfs(int u, int father) {for (auto i : v[u]) {if (i.first != father) {if (!color[i.first]) {color[i.first] = 3 - color[u];dfs(i.first, u);} else if (color[i.first] != 3 - color[u]) {flag = true;}}}
}
signed main() {ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);cin >> n >> m;for (int i = 1; i <= m; i ++) {cin >> a[i].op >> a[i].x >> a[i].y;v[a[i].x].push_back({a[i].y, a[i].op});v[a[i].y].push_back({a[i].x, a[i].op});}for (int i = 1; i <= n; i ++) {if (!color[i]) {color[i] = 1;dfs(i, i);}}if (flag) {cout << "NO";return 0;}for (int i = 1; i <= m; i ++) {if (a[i].op == 1) {if (color[a[i].x] == 1) {v1[a[i].x].push_back(a[i].y);num[a[i].y] ++;} else {v1[a[i].y].push_back(a[i].x);num[a[i].x] ++;}} else if (a[i].op == 2) {if (color[a[i].x] == 1) {v1[a[i].y].push_back(a[i].x);num[a[i].x] ++;} else {v1[a[i].x].push_back(a[i].y);num[a[i].y] ++;}}}for (int i = 1; i <= n; i ++) {if (num[i] == 0) {q.push(i);}}int cnt = 0;while (!q.empty()) {int u = q.front();q.pop();ans[u] = ++cnt;for (auto i : v1[u]) {num[i] --;if (num[i] == 0) {q.push(i);}}}for (int i = 1; i <= n; i ++) {if (ans[i] == 0) {cout << "NO";return 0;}}cout << "YES\n";for (int i = 1; i <= n; i ++) {if (color[i] == 1) {cout << "L " << ans[i] << "\n";} else {cout << "R " << ans[i] << "\n";}}return 0;
}
