Luogu4652 CEOI2017 One-Way Streets 树上差分
题意:给出$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 树上差分的更多相关文章
- loj2480 [CEOI2017]One-Way Streets 边双+树上差分
边双无法确定 缩完边双就是一棵树 树上差分随意弄一下吧... #include <vector> #include <cstdio> #include <cstring& ...
- 【BZOJ-4326】运输计划 树链剖分 + 树上差分 + 二分
4326: NOIP2015 运输计划 Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 703 Solved: 461[Submit][Status] ...
- [luogu P3128][USACO15DEC]Max Flow [LCA][树上差分]
题目描述 Farmer John has installed a new system of pipes to transport milk between the stalls in his b ...
- 树上差分 (瞎bb) [树上差分][LCA]
做noip2015的运输计划写了好久好久写不出来 QwQ 于是先来瞎bb一下树上差分 混积分 树上差分有2个常用的功能: (1)记录从点i到i的父亲这条路径走过几次 (2)将每条路径(s,t ...
- [填坑]树上差分 例题:[JLOI2014]松鼠的新家(LCA)
今天算是把LCA这个坑填上了一点点,又复习(其实是预习)了一下树上差分.其实普通的差分我还是会的,树上的嘛,也是懂原理的就是没怎么打过. 我们先来把树上差分能做到的看一下: 1.找所有路径公共覆盖的边 ...
- 【NOIP2016】【LCA】【树上差分】【史诗级难度】天天爱跑步
学弟不是说要出丧题吗>>所以我就研究了1天lca又研究了1天tj然后研究了一天天天爱跑步,终于写了出来.(最后的平均用时为240ms...比学弟快了1倍...) 题意:给你颗树,然后有m个 ...
- BZOJ_4238_电压_树上差分+dfs树
BZOJ_4238_电压_树上差分+dfs树 Description 你知道Just Odd Inventions社吗?这个公司的业务是“只不过是奇妙的发明(Just Odd Inventions)” ...
- BZOJ_3307_雨天的尾巴_线段树合并+树上差分
BZOJ_3307_雨天的尾巴_线段树合并 Description N个点,形成一个树状结构.有M次发放,每次选择两个点x,y 对于x到y的路径上(含x,y)每个点发一袋Z类型的物品.完成 所有发放后 ...
- [GXOI/GZOI2019]旧词(树上差分+树剖)
前置芝士:[LNOI2014]LCA 要是这题放HNOI就好了 原题:\(\sum_{l≤i≤r}dep[LCA(i,z)]\) 这题:\(\sum_{i≤r}dep[LCA(i,z)]^k\) 对于 ...
随机推荐
- vue-cli脚手架之package.json
package.json文件配置及其含义,这个是vue-cli自动生成的文件,先贴一张代码及其含义: { "name": "secondproject",//模 ...
- IOS 多文件上传 Java web端(后台) 使用List<MultipartFile> 接收出现的问题
先上正确的示例: 主要是设置我们的request的content-type为multipart/form-data NSDictionary *param = @{@"assignee&qu ...
- MySQL写入用户微信名
很简单的需求,将用户微信名写入MySQl即可,但是测试过程中却遇到了问题,微信名中的emoji写入数据库失败.解决步骤如下 1.了解utf8mb4 MySQL从5.5.3版本开始支持utf8mb4编码 ...
- HTML5文件API之FileReader
在文件上传之前,我们总想预览一下文件内容,或图片样子,html5 中FileReader正好提供了2种方法,可以在不上传文件的情况下,预览文件内容. 图片预览:readAsDataURL(file); ...
- python第四十八天--高级FTP
高级FTP服务器1. 用户加密认证2. 多用户同时登陆3. 每个用户有自己的家目录且只能访问自己的家目录4. 对用户进行磁盘配额.不同用户配额可不同5. 用户可以登陆server后,可切换目录6. 查 ...
- Mouse Without Borders软件,主要功能备忘录
详细地址:https://blog.csdn.net/andylauren/article/details/64540500
- centos7下安装docker(13docker存储)
Docker为容器提供了两种存放数据的资源: 1.storage driver管理的镜像层和容器层 2.Data volume Storage driver 之前我们学习镜像的时候知道镜像的分层结构: ...
- P1057 传球游戏
题目描述 上体育课的时候,小蛮的老师经常带着同学们一起做游戏.这次,老师带着同学们一起做传球游戏. 游戏规则是这样的: nnn 个同学站成一个圆圈,其中的一个同学手里拿着一个球,当老师吹哨子时开始传球 ...
- nodejs-stream部分
参考: https://blog.csdn.net/eeewwwddd/article/details/81042225 http://nodejs.cn/api/stream.html#stream ...
- RMAN 数据库克隆文件位置转换方法
在使用RMAN克隆数据库时,如果辅助数据库(新数据库)使用了与目标数据库(原数据库)使用了不同的路径,那么就存在位置转换的问题.在Oracle中,控制文件用于定位数据文件以及联机重做日志文件,如果没有 ...