题目给出n个车辆,给出类型和两个车辆的编号:
让我们还原每辆车的方向和位置,保证这些车辆符合题目所给的条件。
首先先用染色法判断是不是二分图,不是的话直接输出NO。
是二分图的话,那么我们重新建图,坐标在左边的点向在右边的点建一条边,再进行拓扑排序,拓扑排序序列即为从左到右的汽车位置,如果不能拓扑排序,则说明存在环,不符合题目条件。
#include
#include
#include
using namespace std;
const int N = 200010, M = N*2;
int n, m;
int h[N], e[M], ne[M], w[M], idx;
int color[N];
bool flag = true;
int q[N], hh = 0, tt = -1;
int in[N];
int aa[N], bb[N], opp[N];
int x[N];
void add(int a, int b)
{
e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}
void dfs(int u, int c)
{
color[u] = c;
for(int i = h[u]; i != -1; i = ne[i])
{
int j = e[i];
if(color[j])
{
if(color[j] == c)
{
flag = false;
}
}else
{
dfs(j, 3-c);
}
}
}
int main()
{
scanf("%d%d", &n, &m);
memset(h, -1, sizeof h);
for(int i = 1; i <= m; i ++){
scanf("%d%d%d", &opp[i], &aa[i], &bb[i]);
add(aa[i], bb[i]), add(bb[i], aa[i]);
}
for(int i = 1; i <= n; i ++)
{
if(color[i] == 0)
{
dfs(i, 1);
}
}
if(!flag)
{
puts("NO");
return 0;
}
memset(h, -1, sizeof h);
memset(e, 0, sizeof e);
memset(ne, 0, sizeof ne);
memset(w, 0, sizeof w);
idx = 0;
for(int i = 1; i <= m; i ++)
{
int op = opp[i], a = aa[i], b = bb[i];
if(op == 1)
{
if(color[a] == 1)
{
add(a, b);
in[b] ++;
}else
{
add(b, a);
in[a] ++;
}
}else
{
if(color[a] == 1)
{
add(b, a);
in[a] ++;
}else
{
add(a, b);
in[b] ++;
}
}
}
for(int i = 1; i <= n; i ++)
{
if(in[i] == 0)
{
q[++tt] = i;
}
}
int cnt = 0;
while(hh <= tt)
{
int t = q[hh++];
x[t] = ++ cnt;
for(int i = h[t]; i != -1; i = ne[i])
{
int j = e[i];
if(--in[j] == 0)
{
q[++tt] = j;
}
}
}
if(tt != (n-1))
{
puts("NO");
return 0;
}
puts("YES");
for(int i = 1; i <= n; i ++)
{
cout << (color[i] == 1 ? "L " : "R ");
cout << x[i] << endl;
}
return 0;
}