Codeforces 1635E Cars 题解

题目简述

一条数轴上有 \(n\) 辆车,每辆车都可以向左或向右定向移动,并且可以随时以任何恒定的正速度沿该方向移动。两辆车之间可以有以下两种关系:

  • 如果两辆汽车无论速度如何都永远不会到达同一点,我们称它们为 无关紧要的

  • 如果两辆汽车无论速度如何,它们一定会到达同一点,我们称它们为 命中注定的

现在给定 \(m\) 条关系,你要确定每辆车初始的位置与方向,满足这 \(m\) 条关系。

题目分析

首先,我们可以通过模拟发现如果两辆车是 无关紧要的,它们只能是相背而行。同理,如果两辆车是 命中注定的,它们则是相对而行。也就是说,无论给出那种关系,他们的方向必定是相反的,这启发我们使用二分图染色来确定他们的方向。

如果不是二分图,那必定无解。如果是,我们就让染成黑色的向左行驶,染成白色的向右行驶。当然,相反也是可以的。

接下来,我们考虑如何确定他们的位置,我们可以枚举每一对关系,为了方便一些,我们设 \(i\) 为向右行驶的车,\(j\) 为向左行驶的车。我们分成两种情况来讨论:

  • 如果两辆车是 命中注定的,那么 \(i\) 一定在 \(j\) 的前方,读者可以画图模拟一下,这说明 \(i\) 的坐标 \(x_i\) 一定小于 \(j\) 的坐标 \(x_j\),即 \(x_i \lt x_j\)

  • 同理,如果两辆车是 无关紧要的,那么 \(j\) 一定在 \(i\) 的前方,这说明 \(x_j \lt x_i\)

现在问题被转化成了给出 \(m\) 条形如 \(A \lt B\) 的关系,让你对其排序。我们可以利用 P1347 排序 的做法,分别建立一条 \(A \to B\) 的有向边,再进行拓扑排序,最后按出队顺序赋值即可,当然,如果图中有环的话就是无解。

代码

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int n,m,opt[N],x[N],y[N],col[N],tot,ans[N],in[N];
vector<int> G1[N],G2[N];
queue<int> q;
bool dfs(int u,int c)
{
	col[u]=c;
	for(int v:G1[u])
	{
		if(col[v]==c||(col[v]==-1&&!dfs(v,c^1))) return 0;
	}
	return 1;
}
bool topo()
{
	for(int i=1;i<=n;i++)
	{
		if(!in[i]) q.push(i);
	}
	while(!q.empty())
	{
		int u=q.front();
		q.pop();
		ans[u]=tot++;
		for(int v:G2[u])
		{
			if(!(--in[v]))
			{
				q.push(v);
			}
		}
	}
	return tot<n?1:0;
}
int main()
{
	cin>>n>>m;
	memset(col,-1,sizeof col);
	for(int i=1;i<=m;i++)
	{
		cin>>opt[i]>>x[i]>>y[i];
		G1[x[i]].push_back(y[i]);
		G1[y[i]].push_back(x[i]);
	}
	for(int i=1;i<=n;i++)
	{
		if(col[i]==-1)
		{
			if(!dfs(i,0))
			{
				printf("NO\n");
				return 0;
			}
		}
	}
	for(int i=1;i<=m;i++)
	{
		if(opt[i]==1)
		{
			if(col[x[i]]==1&&col[y[i]]==0)
			{
				G2[y[i]].push_back(x[i]);
				in[x[i]]++;
			}
			else
			{
				G2[x[i]].push_back(y[i]);
				in[y[i]]++;
			}
		}
		else
		{
			if(col[x[i]]==1&&col[y[i]]==0)
			{
				G2[x[i]].push_back(y[i]);
				in[y[i]]++;
			}
			else
			{
				G2[y[i]].push_back(x[i]);
				in[x[i]]++;
			}
		}
	}
	if(topo())
	{
		printf("NO");
		return 0;
	}
	printf("YES\n");
	for(int i=1;i<=n;i++)
	{
		cout<<(!col[i]?'L':'R')<<" "<<ans[i]<<"\n";
	}
	return 0;
}
posted @ 2024-01-30 14:59  zhuluoan  阅读(45)  评论(0)    收藏  举报