传送门

题意:给出$N$个点、$M$条无向边的图,现在你需要给它定向,并满足$Q$个条件:每个条件形如$(x_i,y_i)$,表示定向之后需要存在路径从$x_i$走向$y_i$。问每条边是否都有唯一定向方式。$N,M,Q \leq 10^5$


图论总是涉及的算法不难,但是就是脑子生锈想不出来

可以知道一个边双联通分量里面的所有边的方向都是一定不能确定的,因为如果存在一种方式满足所有条件,将这个边双联通分量里的所有边取反之后也一定满足条件。所以我们只需要考虑割边。

不妨在原图中找到一棵树,这棵树上必定包含所有的割边。通过差分将非割边打上标记,我们就可以通过在新的树上求$LCA$加上差分对所有边向上还是向下打好标记,最后$dfs$求出答案即可。

实际上还可以并查集,但是并查集写炸了qwq

注意重边,还要注意图不连通的情况

 #include<bits/stdc++.h>
using namespace std; inline int read(){
int a = ;
bool f = ;
char c = getchar();
while(c != EOF && !isdigit(c)){
if(c == '-')
f = ;
c = getchar();
}
while(c != EOF && isdigit(c)){
a = (a << ) + (a << ) + (c ^ '');
c = getchar();
}
return f ? -a : a;
} const int MAXN = ;
struct Edge{
int end , upEd;
}Ed[MAXN << ];
int N , M , cntEd = , head[MAXN] , dep[MAXN] , up[MAXN] , down[MAXN] , can[MAXN] , jump[MAXN][];
char ans[MAXN];
bool vis[MAXN]; inline void addEd(int a , int b){
Ed[++cntEd].end = b;
Ed[cntEd].upEd = head[a];
head[a] = cntEd;
} void dfs(int x , int fa){
jump[x][] = fa;
dep[x] = dep[fa] + ;
for(int i = ; i <= ; i++)
jump[x][i] = jump[jump[x][i - ]][i - ];
for(int i = head[x] ; i ; i = Ed[i].upEd)
if(!dep[Ed[i].end])
dfs(Ed[i].end , x);
else
if(dep[Ed[i].end] > dep[x]){
can[Ed[i].end]++;
can[x]--;
}
} void Dfs(int x){
vis[x] = ;
for(int i = head[x] ; i ; i = Ed[i].upEd)
if(dep[Ed[i].end] == dep[x] + && !vis[Ed[i].end]){//不加vis判断会炸!!!
Dfs(Ed[i].end);
if(can[Ed[i].end] == )
if((i & ) && up[Ed[i].end] || !(i & ) && down[Ed[i].end])
ans[i >> ] = 'R';
else
if(!(i & ) && up[Ed[i].end] || (i & ) && down[Ed[i].end])
ans[i >> ] = 'L';
up[x] += up[Ed[i].end];
down[x] += down[Ed[i].end];
can[x] += can[Ed[i].end];
}
} inline int jumpToLCA(int x , int y){
if(dep[x] < dep[y])
swap(x , y);
for(int i = ; i >= ; i--)
if(dep[x] - ( << i) >= dep[y])
x = jump[x][i];
if(x == y)
return x;
for(int i = ; i >= ; i--)
if(jump[x][i] != jump[y][i]){
x = jump[x][i];
y = jump[y][i];
}
return jump[x][];
} int main(){
#ifdef LG
freopen("4652.in" , "r" , stdin);
freopen("4652.out" , "w" , stdout);
#endif
N = read();
M = read();
for(int i = ; i <= M ; i++){
int a = read() , b = read();
addEd(a , b);
addEd(b , a);
}
for(int i = ; i <= N ; i++)
if(!dep[i])
dfs(i , );
for(int Q = read() ; Q ; Q--){
int a = read() , b = read() , t = jumpToLCA(a , b);
up[a]++;
up[t]--;
down[t]--;
down[b]++;
}
memset(ans , 'B' , sizeof(ans));
for(int i = ; i <= N ; i++)
if(!vis[i])
Dfs(i);
for(int i = ; i <= M ; i++)
cout << ans[i];
return ;
}

Luogu4652 CEOI2017 One-Way Streets 树上差分的更多相关文章

  1. loj2480 [CEOI2017]One-Way Streets 边双+树上差分

    边双无法确定 缩完边双就是一棵树 树上差分随意弄一下吧... #include <vector> #include <cstdio> #include <cstring& ...

  2. 【BZOJ-4326】运输计划 树链剖分 + 树上差分 + 二分

    4326: NOIP2015 运输计划 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 703  Solved: 461[Submit][Status] ...

  3. [luogu P3128][USACO15DEC]Max Flow [LCA][树上差分]

    题目描述 Farmer John has installed a new system of  pipes to transport milk between the  stalls in his b ...

  4. 树上差分 (瞎bb) [树上差分][LCA]

    做noip2015的运输计划写了好久好久写不出来   QwQ 于是先来瞎bb一下树上差分    混积分 树上差分有2个常用的功能: (1)记录从点i到i的父亲这条路径走过几次 (2)将每条路径(s,t ...

  5. [填坑]树上差分 例题:[JLOI2014]松鼠的新家(LCA)

    今天算是把LCA这个坑填上了一点点,又复习(其实是预习)了一下树上差分.其实普通的差分我还是会的,树上的嘛,也是懂原理的就是没怎么打过. 我们先来把树上差分能做到的看一下: 1.找所有路径公共覆盖的边 ...

  6. 【NOIP2016】【LCA】【树上差分】【史诗级难度】天天爱跑步

    学弟不是说要出丧题吗>>所以我就研究了1天lca又研究了1天tj然后研究了一天天天爱跑步,终于写了出来.(最后的平均用时为240ms...比学弟快了1倍...) 题意:给你颗树,然后有m个 ...

  7. BZOJ_4238_电压_树上差分+dfs树

    BZOJ_4238_电压_树上差分+dfs树 Description 你知道Just Odd Inventions社吗?这个公司的业务是“只不过是奇妙的发明(Just Odd Inventions)” ...

  8. BZOJ_3307_雨天的尾巴_线段树合并+树上差分

    BZOJ_3307_雨天的尾巴_线段树合并 Description N个点,形成一个树状结构.有M次发放,每次选择两个点x,y 对于x到y的路径上(含x,y)每个点发一袋Z类型的物品.完成 所有发放后 ...

  9. [GXOI/GZOI2019]旧词(树上差分+树剖)

    前置芝士:[LNOI2014]LCA 要是这题放HNOI就好了 原题:\(\sum_{l≤i≤r}dep[LCA(i,z)]\) 这题:\(\sum_{i≤r}dep[LCA(i,z)]^k\) 对于 ...

随机推荐

  1. JS性能优化 之 事件委托

    面试中2次被问到过这个知识点,实际开发中,应用事件委托也比较常见.JS中事件委托的实现主要依赖于 事件冒泡 .那什么是事件冒泡?就是事件从最深的节点开始,然后逐步向上传播事件,举个例子:页面上有这么一 ...

  2. Git应用—03分支管理和冲突解决(转载)

    Git 分支管理和冲突解决 https://www.cnblogs.com/mengdd/p/3585038.html 创建分支 git branch 没有参数,显示本地版本库中所有的本地分支名称. ...

  3. Flutter 依赖的那些事儿

    Flutter 里面有2种库一样的东西, Package -creating a pure Dart component. like a new Widget. 这种是纯Dart,相当于你自己写的组件 ...

  4. java代码代替xml实现图片

    1.使用StateListDrawable替换selector public static StateListDrawable getSelector(Drawable normalDrawable, ...

  5. 输入两个整数n和m,从数列1,2,3,……n中随意取几个数,使其和等于m

    题目:编程求解,输入两个整数n和m,从数列1,2,3,……n中随意取几个数,使其和等于m.要求将所有的可能组合列出来. 分析:分治的思想.可以把问题(m,n)拆分(m - n, n -1)和(m, n ...

  6. 理解ES6中的Promise

    一.Promise的作用 在ajax请求数据的过程中,我们可以异步拿到我们想要的数据,然后在回调中做相应的数据处理. 这样做看上去并没有什么麻烦,但是如果这个时候,我们还需要做另外一个ajax请求,这 ...

  7. Django 添加mdia文件目录路径

    1.settings.py MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(BASE_DIR, 'media') 2.urls.py from djan ...

  8. VMware-workstation12.5.6 新建虚拟机 安装 centos6.5

    1.到官方下载镜像文件 注意:看到上面那两个红框不要着急复制链接用迅雷下载,因为点击进去是个页面,不知道官方做这个用意是怎样的,个人感觉很傻缺我们只要点击第一个红框就行 *************** ...

  9. tkinter中Radiobutton单选框控件(七)

    Radiobutton控件 由于本次内容中好多知识都是之前重复解释过的,本次就不做解释了.不太清楚的内容请参考tkinter1-6节中的内容 import tkinter wuya = tkinter ...

  10. Ubuntu 16.04 LTS 降级安装GCC 4.8

    转载自https://www.linuxidc.com/Linux/2017-03/142299.htm Ubuntu 16.04 LTS 降级安装GCC 4.8 [日期:2017-03-28] 来源 ...