思路
分析题目可得无论op是多少,i,j必定反向,op为1,posi<posj,否则posi>posj。
采用二分图染色法,col=2表示L,col=3表示R,然后根据ij的位置关系由小向大建边,最后跑一遍拓扑即可
Code
#include <bits/stdc++.h>
#pragma GCC optimize(2)
#define debug freopen("_in.txt", "r", stdin);
// #define debug freopen("_in.txt", "r", stdin), freopen("_out.txt", "w", stdout);
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll maxn = 3e5 + 10;
const ll maxm = 1e4 + 10;
const ll mod = 1e9 + 7;
const double pi = acos(-1);
const double eps = 1e-8;
ll n, m;
ll col[maxn], ind[maxn], res[maxn];
ll flag = 1;
struct Edge
{
ll op, u, v;
} edges[maxn];
vector<ll> to1[maxn], to2[maxn];
queue<ll> que;
void dfs(ll u, ll color, ll fa)
{
col[u] = color;
for (auto v : to1[u])
{
if (v == fa)
continue;
else if (col[v])
{
if (col[v] == col[u])
{
flag = 0;
}
}
else
{
dfs(v, color ^ 1, u);
}
}
}
int main()
{
// debug;
scanf("%lld%lld", &n, &m);
for (ll i = 1; i <= m; i++)
{
ll op, u, v;
scanf("%lld%lld%lld", &op, &u, &v);
edges[i] = {
op, u, v};
to1[u].push_back(v);
to1[v].push_back(u);
}
for (ll i = 1; i <= n; i++)
{
if (!col[i])
{
dfs(i, 2, 0);
}
}
for (ll i = 1; i <= m; i++)
{
ll op, u, v;
op = edges[i].op;
u = edges[i].u;
v = edges[i].v;
if (col[u] == 3)
swap(u, v);
if (op == 1)
{
to2[u].push_back(v);
ind[v]++;
}
else
{
to2[v].push_back(u);
ind[u]++;
}
}
for (ll i = 1; i <= n; i++)
{
if (ind[i] == 0)
que.push(i);
}
ll pos = 0;
while (!que.empty())
{
ll u = que.front();
que.pop();
res[u] = ++pos;
for (auto v : to2[u])
{
ind[v]--;
if (ind[v] == 0)
que.push(v);
}
}
for (ll i = 1; i <= n; i++)
{
if(!res[i]) flag=0;
}
if (!flag)
{
printf("NO\n");
return 0;
}
else
{
printf("YES\n");
for (ll i = 1; i <= n; i++)
{
if(col[i]==2)
{
printf("L %lld\n",res[i]);
}
else
{
printf("R %lld\n",res[i]);
}
}
}
}