题目描述

给定一张 \(n\) 个点 \(m\) 条边的无向图,现在想要把这张图定向。

有 \(p\) 个限制条件,每个条件形如 \((xi,yi)\) ,表示在新的有向图当中,\(x_i\) 要能够沿着一些边走到 \(y_i\) ​​。

现在请你求出,每条边的方向是否能够唯一确定。同时请给出这些能够唯一确定的边的方向。

输入格式

第一行两个空格隔开的正整数 \(n,m\) 。

接下来 \(m\) 行,每行两个空格隔开的正整数 \(a_i,b_i\) ,表示 \(a_i,b_i\) 之间有一条边。

接下来一行一个整数 \(p\),表示限制条件的个数。

接下来 \(p\) 行,每行两个空格隔开的正整数 \(x_i,y_i\),描述一个 \((x_i,y_i)\) 的限制条件。

输出格式

输出一行一个长度为 \(m\) 的字符串,表示每条边的答案:

  • 若第 \(i\) 条边必须得要是 \(a_i\)​​ 指向 \(b_i\) 的,那么这个字符串的第 \(i\) 个字符应当为 R

  • 若第 \(i\) 条边必须得要是 \(b_i\) 指向 \(a_i\) 的,那么这个字符串的第 \(i\) 个字符应当为 L

  • 否则,若第 \(i\) 条边的方向无法唯一确定,那么这个字符串的第 \(i\) 个字符应当为 B

样例

样例输入

  1. 5 6
  2. 1 2
  3. 1 2
  4. 4 3
  5. 2 3
  6. 1 3
  7. 5 1
  8. 2
  9. 4 5
  10. 1 3

样例输出

  1. BBRBBL

数据范围与提示

对于所有测试点,有 \(1\le n,m,p\le 100\ 000;1\le a_i,b_i,x_i,y_i\le n\) 。

  • 子任务 1(\(30\%\)):有 \(n,m\le 1000;p\le 100\) ;

  • 子任务 2(\(30\%\)):有 \(p\le 100\) ;

  • 子任务 3(\(40\%\)):无特殊限制。

题解

在同一个点双内的显然不能完全确定

所以先Tarjan找点双并缩点

对于剩下的点与询问,就是在一棵树上了,随便搞一搞就好了

我是用的一种奇怪的方法

对于一个点,它的权值记录了它和它的父亲之间的边的方向

对于一个询问,找到询问中两个点的LCA,然后在两个点都打上LCA的标记,代表它们到LCA的这段路径上的所有边的方向全部为某个方向

由于题目保证无冲突,所以是不会有一条边会被赋值两次的

所有标记打完后,一遍dfs处理完所有标记就好了

  1. #include<bits/stdc++.h>
  2. #define ui unsigned int
  3. #define ll long long
  4. #define db double
  5. #define ld long double
  6. #define ull unsigned long long
  7. const int MAXN=100000+10,inf=0x3f3f3f3f;
  8. int n,m,q,e=1,beg[MAXN],nex[MAXN<<1],to[MAXN<<1],DFN[MAXN],LOW[MAXN],Visit_Num,bridge[MAXN<<1],cnt,bel[MAXN],qto[MAXN<<1],qnex[MAXN<<1],qbeg[MAXN],Jie[MAXN][21],up[MAXN],dep[MAXN],qe,mk[MAXN],ps[MAXN],nt;
  9. struct node{
  10. int u,v;
  11. };
  12. node side[MAXN];
  13. template<typename T> inline void read(T &x)
  14. {
  15. T data=0,w=1;
  16. char ch=0;
  17. while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
  18. if(ch=='-')w=-1,ch=getchar();
  19. while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();
  20. x=data*w;
  21. }
  22. template<typename T> inline void write(T x,char ch='\0')
  23. {
  24. if(x<0)putchar('-'),x=-x;
  25. if(x>9)write(x/10);
  26. putchar(x%10+'0');
  27. if(ch!='\0')putchar(ch);
  28. }
  29. template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
  30. template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
  31. template<typename T> inline T min(T x,T y){return x<y?x:y;}
  32. template<typename T> inline T max(T x,T y){return x>y?x:y;}
  33. inline void insert(int x,int y)
  34. {
  35. to[++e]=y;
  36. nex[e]=beg[x];
  37. beg[x]=e;
  38. }
  39. inline void qinsert(int x,int y)
  40. {
  41. qto[++qe]=y;
  42. qnex[qe]=qbeg[x];
  43. qbeg[x]=qe;
  44. }
  45. inline void Tarjan(int x,int f)
  46. {
  47. DFN[x]=LOW[x]=++Visit_Num;ps[x]=nt;
  48. for(register int i=beg[x];i;i=nex[i])
  49. if(!DFN[to[i]])
  50. {
  51. Tarjan(to[i],x);
  52. chkmin(LOW[x],LOW[to[i]]);
  53. if(LOW[to[i]]>DFN[x])bridge[i]=bridge[i^1]=1;
  54. }
  55. else if(DFN[to[i]]<DFN[x]&&to[i]!=f)chkmin(LOW[x],DFN[to[i]]);
  56. }
  57. inline void dfs(int x)
  58. {
  59. DFN[x]=1;bel[x]=cnt;
  60. for(register int i=beg[x];i;i=nex[i])
  61. if(bridge[i])continue;
  62. else if(!DFN[to[i]])dfs(to[i]);
  63. }
  64. inline void idfs(int x,int f)
  65. {
  66. Jie[x][0]=f;dep[x]=dep[f]+1;
  67. for(register int i=qbeg[x];i;i=qnex[i])
  68. if(qto[i]==f)continue;
  69. else idfs(qto[i],x);
  70. }
  71. inline void init()
  72. {
  73. for(register int j=1;j<=19;++j)
  74. for(register int i=1;i<=cnt;++i)Jie[i][j]=Jie[Jie[i][j-1]][j-1];
  75. }
  76. inline int LCA(int u,int v)
  77. {
  78. if(dep[u]<dep[v])std::swap(u,v);
  79. if(dep[u]>dep[v])
  80. for(register int i=19;i>=0;--i)
  81. if(dep[Jie[u][i]]>=dep[v])u=Jie[u][i];
  82. if(u==v)return u;
  83. for(register int i=19;i>=0;--i)
  84. if(Jie[u][i]!=Jie[v][i])u=Jie[u][i],v=Jie[v][i];
  85. return Jie[u][0];
  86. }
  87. inline void edfs(int x,int f)
  88. {
  89. for(register int i=qbeg[x];i;i=qnex[i])
  90. if(qto[i]!=f)edfs(qto[i],x),chkmin(up[x],up[qto[i]]);
  91. if(up[x]<dep[f])mk[f]=mk[x];
  92. }
  93. int main()
  94. {
  95. read(n);read(m);
  96. for(register int i=1;i<=m;++i)
  97. {
  98. int u,v;read(u);read(v);
  99. insert(u,v);insert(v,u);
  100. side[i]=(node){u,v};
  101. }
  102. for(register int i=1;i<=n;++i)
  103. if(!DFN[i])++nt,Tarjan(i,0);
  104. memset(DFN,0,sizeof(DFN));
  105. for(register int i=1;i<=n;++i)
  106. if(!DFN[i])++cnt,dfs(i);
  107. for(register int i=1,u,v;i<=m;++i)
  108. if((u=bel[side[i].u])!=(v=bel[side[i].v]))qinsert(u,v),qinsert(v,u);
  109. for(register int i=1;i<=cnt;++i)
  110. if(!dep[i])idfs(i,0);
  111. init();
  112. memset(up,inf,sizeof(up));
  113. read(q);
  114. while(q--)
  115. {
  116. int x,y,lca;read(x);read(y);
  117. if(bel[x]==bel[y]||ps[x]!=ps[y])continue;
  118. x=bel[x],y=bel[y];lca=LCA(x,y);
  119. if(x!=lca)chkmin(up[x],dep[lca]),mk[x]=-1;
  120. if(y!=lca)chkmin(up[y],dep[lca]),mk[y]=1;
  121. }
  122. edfs(1,0);
  123. for(register int i=1,u,v;i<=m;++i)
  124. {
  125. u=side[i].u,v=side[i].v;
  126. if(bel[u]==bel[v])putchar('B');
  127. else
  128. {
  129. u=bel[u],v=bel[v];
  130. if(dep[u]>dep[v])
  131. {
  132. if(mk[u]==-1)putchar('R');
  133. else if(mk[u]==1)putchar('L');
  134. else putchar('B');
  135. }
  136. else
  137. {
  138. if(mk[v]==-1)putchar('L');
  139. else if(mk[v]==1)putchar('R');
  140. else putchar('B');
  141. }
  142. }
  143. }
  144. puts("");
  145. return 0;
  146. }

【刷题】LOJ 2480 「CEOI2017」One-Way Streets的更多相关文章

  1. @loj - 2480@ 「CEOI2017」One-Way Streets

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定一张 n 个点 m 条边的无向图,现在想要把这张图定向. 有 ...

  2. loj#2483. 「CEOI2017」Building Bridges 斜率优化 cdq分治

    loj#2483. 「CEOI2017」Building Bridges 链接 https://loj.ac/problem/2483 思路 \[f[i]=f[j]+(h[i]-h[j])^2+(su ...

  3. loj#2483. 「CEOI2017」Building Bridges(dp cdq 凸包)

    题意 题目链接 Sol \[f[i], f[j] + (h[i] - h[j])^2 + (w[i - 1] - w[j]))\] 然后直接套路斜率优化,发现\(k, x\)都不单调 写个cdq就过了 ...

  4. 【动态规划】loj#2485. 「CEOI2017」Chase

    有意思的可做dp题:细节有点多,值得多想想 题目描述 在逃亡者的面前有一个迷宫,这个迷宫由 nnn 个房间和 n−1n-1n−1 条双向走廊构成,每条走廊会链接不同的两个房间,所有的房间都可以通过走廊 ...

  5. @loj - 2483@「CEOI2017」Building Bridges

    目录 @desription@ @solution@ @accepted code@ @details@ @another solution@ @another code@ @desription@ ...

  6. Loj 3058. 「HNOI2019」白兔之舞

    Loj 3058. 「HNOI2019」白兔之舞 题目描述 有一张顶点数为 \((L+1)\times n\) 的有向图.这张图的每个顶点由一个二元组 \((u,v)\) 表示 \((0\le u\l ...

  7. LOJ #6436. 「PKUSC2018」神仙的游戏(字符串+NTT)

    题面 LOJ #6436. 「PKUSC2018」神仙的游戏 题解 参考 yyb 的口中的长郡最强选手 租酥雨大佬的博客 ... 一开始以为 通配符匹配 就是类似于 BZOJ 4259: 残缺的字符串 ...

  8. LOJ #6435. 「PKUSC2018」星际穿越(倍增)

    题面 LOJ#6435. 「PKUSC2018」星际穿越 题解 参考了 这位大佬的博客 这道题好恶心啊qwq~~ 首先一定要认真阅读题目 !! 注意 \(l_i<r_i<x_i\) 这个条 ...

  9. LOJ #6432. 「PKUSC2018」真实排名(组合数)

    题面 LOJ #6432. 「PKUSC2018」真实排名 注意排名的定义 , 分数不小于他的选手数量 !!! 题解 有点坑的细节题 ... 思路很简单 , 把每个数分两种情况讨论一下了 . 假设它为 ...

随机推荐

  1. C# 通用树形数据结构

    前言 树在图论中是一种重要的图,由于其自身的许多特殊性质,也是一种重要的计算机数据结构,在很多地方都有用.但是这些树大多都是作为其他应用的内部数据结构来使用.我们无法了解这些树的详细信息,而 .Net ...

  2. Spark聚合操作:combineByKey()

    Spark中对键值对RDD(pairRDD)基于键的聚合函数中,都是通过combineByKey()实现的. 它可以让用户返回与输入数据类型不同的返回值(可以自己配置返回的参数,返回的类型) 首先理解 ...

  3. jar包、war包

    JavaSE程序可以打包成Jar包(J其实可以理解为Java了),而JavaWeb程序可以打包成war包(w其实可以理解为Web了).然后把war发布到Tomcat的webapps目录下,Tomcat ...

  4. python3 拼接字符串的7种方法

    1.直接通过(+)操作符拼接 1 2 >>> 'Hello' + ' ' + 'World' + '!' 'Hello World!' 使用这种方式进行字符串连接的操作效率低下,因为 ...

  5. NDK 链接第三方静态库的方法

    将NDK编译的第三方静态拷贝到JNI目录下,在Android.mk中添加如下代码 以openssl静态库(libcrypto-static.a)为例 第一种链接方法:LOCAL_LDFLAGS := ...

  6. users命令详解

    基础命令学习目录 原文链接:https://blog.csdn.net/m0_38132420/article/details/78861464 users命令用于显示当前登录系统所有的用户的用户列表 ...

  7. 用python实现数字图片识别神经网络--启动网络的自我训练流程,展示网络数字图片识别效果

    上一节,我们完成了网络训练代码的实现,还有一些问题需要做进一步的确认.网络的最终目标是,输入一张手写数字图片后,网络输出该图片对应的数字.由于网络需要从0到9一共十个数字中挑选出一个,于是我们的网络最 ...

  8. 字幕字体滚动插件——scroxt.js

    README scroxt.js Overview scroxt.js是一个字体滚动的插件库,包括视频弹幕滚动,直播弹幕.直播弹幕强制模式.单行水平左右滚动.文本垂直滚动上下,用于简单快捷生成滚动字体 ...

  9. 安装AndroidJDK的坑

    最近公司要用weex了,先开始搭一下环境,真的都是坑,写下来大家引以为鉴,我踩坑三天的后果. 首先要安装JavaJDK这个过程就不写了都是程序员网上搜索一下很多,注意找论坛上最新的帖子来看,这里有一个 ...

  10. Leetcode题库——20.有效的括号

    @author: ZZQ @software: PyCharm @file: IsValid.py @time: 2018/9/16 20:20 要求: 给定一个只包括 '(',')','{','}' ...