Codeforces 1635 E. Cars —— 黑白染色+拓扑排序

This way

题意:

现在有n辆车在x轴上,每辆车都在不同的点,并且有一个朝向(左或右),它们会往朝向开。
它们之间有这样的关系:
1 x y表示x和y无论怎么样的速度往前开都不会相遇
2 x y表示x和y无论怎样的速度往前开都会相遇
问你这些车的可能起始位置和朝向

题解

对于1的情况,x和y是相反方向,且在左边的往左,在右边的往右。
对于2的情况,x和y也是相反方向,且在左边的往右,在右边的往左。
那么如果两个车有1或者2的关系,它们的方向就是相反的。那我们随便假设某个车的朝向,然后再对与它在一个连通块的车进行黑白染色,如果不行的话就说明无解。
假设我们按照位置从小到大放,对于一个连边,我们可以假设是有向的:
对于1的情况,我们需要先放0再放1(0向左,1向右),对于2的情况,我们要先放1再放0.
这样就有了一个拓扑结构。

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
vector<int> vec[N];
int x[N],y[N],op[N];
int vis[N];
void dfs(int x){
    for(int ne:vec[x]){
        if(vis[ne]==vis[x]){
            printf("NO\n");
            exit(0);
        }
        if(vis[ne]==-1){
            vis[ne]=vis[x]^1;
            dfs(ne);
        }
    }
}
vector<int>v[N];
int in[N],ans[N];
int main()
{
    memset(vis,-1,sizeof(vis));
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)scanf("%d%d%d",&op[i],&x[i],&y[i]),vec[x[i]].push_back(y[i]),vec[y[i]].push_back(x[i]);
    for(int i=1;i<=n;i++)
        if(vis[i]==-1)
            vis[i]=0,dfs(i);
    for(int i=1;i<=m;i++){
        if(vis[x[i]])swap(x[i],y[i]);
        if(op[i]==1)
            v[x[i]].push_back(y[i]),in[y[i]]++;
        else
            v[y[i]].push_back(x[i]),in[x[i]]++;
    }
    queue<int>Q;
    int now=0;
    for(int i=1;i<=n;i++)
        if(!in[i])
            Q.push(i);
    while(!Q.empty()){
        int u=Q.front();Q.pop();
        ans[u]=++now;
        for(int ne:v[u]){
            in[ne]--;
            if(!in[ne])Q.push(ne);
        }
    }
    if(now!=n)return 0*printf("NO\n");
    printf("YES\n");
    for(int i=1;i<=n;i++)
        printf("%s %d\n",vis[i]?"R":"L",ans[i]);
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值