Codeforces Round #772 (Div. 2) E. Cars

题目给出n个车辆,给出类型和两个车辆的编号:

  • 类型为1,表示两个车辆不会相交
  • 类型为2,表示两个车辆一定会相交

让我们还原每辆车的方向和位置,保证这些车辆符合题目所给的条件。

首先先用染色法判断是不是二分图,不是的话直接输出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;
}

你可能感兴趣的:(c++,cf,动态规划,算法,c++)