题目大意:
  给你一个无向图,现在告诉你一些点对(u,v),
  要你在保证从u到v的所有路径都不变的情况下,尽可能把所有的边变成单向边,
  问你可以唯一确定哪些边的方向,以及方向是从u到v还是从v到u。

思路:
  首先不难发现环上的边都不能确定方向,所以我们可以先缩环。
  缩环以后剩下的图就变成了一棵树,考虑对树进行一些操作来确定边的方向。
  我们可以树链剖分,用线段树维护边的方向,
  但是树上边的方向不一定都是同一种,因此我们可以先不考虑从u到v还是从v到u。
  我们只需要先维护从上到下还是从下到上。
  如果维护时发现当前维护的边的区间已经是有向的,而且和当前方向相反,那么就是双向边。
  最后统计答案时,只需要判一下u在上还是v在上即可。
  小优化:当维护区间已经是双向时,不管怎样它永远都是双向了,我们可以直接在线段树上剪枝。

 #include<stack>
#include<cstdio>
#include<cctype>
#include<vector>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'';
while(isdigit(ch=getchar())) x=(((x<<)+x)<<)+(ch^'');
return x;
}
const int N=,M=;
struct Edge2 {
int u,v;
};
Edge2 edge[M];
struct Edge {
int to,id;
};
std::vector<Edge> e[N];
inline void add_edge(const int &u,const int &v,const int &id) {
e[u].push_back((Edge){v,id});
e[v].push_back((Edge){u,id});
}
char type[M];
std::stack<int> s;
bool mark[M],ins[N];
int dfn[N],low[N],bcc[N];
void tarjan(const int &x) {
s.push(x);
ins[x]=true;
dfn[x]=low[x]=++dfn[];
for(unsigned i=;i<e[x].size();i++) {
const int &y=e[x][i].to,&id=e[x][i].id;
if(mark[id]) continue;
mark[id]=true;
if(!dfn[y]) {
tarjan(y);
low[x]=std::min(low[x],low[y]);
} else if(ins[y]) {
low[x]=std::min(low[x],dfn[y]);
}
}
if(dfn[x]==low[x]) {
bcc[]++;
int y=;
while(y!=x) {
y=s.top();
s.pop();
ins[y]=false;
bcc[y]=bcc[];
}
}
}
int par[N],size[N],dep[N],son[N],top[N],id[N],ori[N];
void dfs1(const int &x,const int &par) {
size[x]=;
::par[x]=par;
dep[x]=dep[par]+;
for(unsigned i=;i<e[x].size();i++) {
const int &y=e[x][i].to;
if(y==par) continue;
dfs1(y,x);
size[x]+=size[y];
if(size[y]>size[son[x]]) son[x]=y;
}
}
void dfs2(const int &x) {
if(x==son[par[x]]) {
top[x]=top[par[x]];
} else {
top[x]=x;
}
if(son[x]) {
id[son[x]]=++id[];
dfs2(son[x]);
}
for(unsigned i=;i<e[x].size();i++) {
const int &y=e[x][i].to;
if(y!=par[x]&&y!=son[x]) {
id[y]=++id[];
dfs2(y);
}
ori[id[y]]=e[x][i].id;
}
}
class SegmentTree {
#define _left <<1
#define _right <<1|1
private:
char val[N<<];
void push_down(const int &p) {
if(!val[p]) return;
if(val[p _left]) {
if(val[p _left]!=val[p]) val[p]='B';
} else {
val[p _left]=val[p];
}
if(val[p _right]) {
if(val[p _right]!=val[p]) val[p]='B';
} else {
val[p _right]=val[p];
}
}
public:
void modify(const int &p,const int &b,const int &e,const int &l,const int &r,const char &c) {
if(val[p]=='B') return;
if(b==l&&e==r) {
if(val[p]) {
if(val[p]!=c) val[p]='B';
} else {
val[p]=c;
}
return;
}
push_down(p);
const int mid=(b+e)>>;
if(l<=mid) modify(p _left,b,mid,l,std::min(mid,r),c);
if(r>mid) modify(p _right,mid+,e,std::max(mid+,l),r,c);
}
void stat(const int &p,const int &b,const int &e) {
if(val[p]=='B') return;
if(b==e) {
if(val[p]) {
type[ori[b]]=val[p];
} else {
type[ori[b]]='B';
}
return;
}
push_down(p);
const int mid=(b+e)>>;
stat(p _left,b,mid);
stat(p _right,mid+,e);
}
#undef _left
#undef _right
};
SegmentTree t;
void modify(int x,int y) {
char c='R',c0='L';
while(top[x]!=top[y]) {
if(dep[top[x]]<dep[top[y]]) {
std::swap(x,y);
std::swap(c,c0);
}
t.modify(,,bcc[],id[top[x]],id[x],c);
x=par[top[x]];
}
if(x==y) return;
if(dep[x]<dep[y]) {
std::swap(x,y);
std::swap(c,c0);
}
t.modify(,,bcc[],id[son[y]],id[x],c);
}
int main() {
const int n=getint(),m=getint();
for(register int i=;i<=m;i++) {
edge[i]=(Edge2){getint(),getint()};
add_edge(edge[i].u,edge[i].v,i);
}
for(register int i=;i<=n;i++) {
if(!dfn[i]) tarjan(i);
e[i].clear();
}
for(register int i=;i<=m;i++) {
const int &u=edge[i].u,&v=edge[i].v;
if(bcc[u]==bcc[v]) {
type[i]='B';
continue;
}
add_edge(bcc[u],bcc[v],i);
}
for(register int i=;i<=bcc[];i++) {
if(!size[i]) {
dfs1(i,);
id[i]=++id[];
dfs2(i);
}
}
for(register int q=getint();q;q--) {
const int x=bcc[getint()],y=bcc[getint()];
modify(x,y);
}
t.stat(,,bcc[]);
for(register int i=;i<=m;i++) {
const int &u=bcc[edge[i].u],&v=bcc[edge[i].v];
if(type[i]!='B'&&dep[u]<dep[v]) {
if(type[i]=='L') {
type[i]='R';
} else {
type[i]='L';
}
}
}
puts(&type[]);
return ;
}

[CEOI2017]One-Way Streets的更多相关文章

  1. 【刷题】LOJ 2480 「CEOI2017」One-Way Streets

    题目描述 给定一张 \(n\) 个点 \(m\) 条边的无向图,现在想要把这张图定向. 有 \(p\) 个限制条件,每个条件形如 \((xi,yi)\) ,表示在新的有向图当中,\(x_i\) 要能够 ...

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

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

  3. Luogu4652 CEOI2017 One-Way Streets 树上差分

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

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

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

  5. One-Way Streets (oneway)

    One-Way Streets (oneway) 题目描述 Once upon a time there was a country with nn cities and mm bidirection ...

  6. Luogu4655 [CEOI2017]Building Bridges

    Luogu4655 [CEOI2017]Building Bridges 有 \(n\) 根柱子依次排列,每根柱子都有一个高度.第 \(i\) 根柱子的高度为 \(h_i\) . 现在想要建造若干座桥 ...

  7. Codeforces 1070J Streets and Avenues in Berhattan dp

    Streets and Avenues in Berhattan 我们首先能发现在最优情况下最多只有一种颜色会分别在行和列, 因为你把式子写出来是个二次函数, 在两端取极值. 然后我们就枚举哪个颜色会 ...

  8. 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 ...

  9. [CEOI2017]Palindromic Partitions

    [CEOI2017]Palindromic Partitions 题目大意: 给出一个长度为\(n(n\le10^6)\)的只包含小写字母字符串,要求你将它划分成尽可能多的小块,使得这些小块构成回文串 ...

随机推荐

  1. Django随笔 01

    Django 视图 不处理用户输入,而仅仅决定要展现哪些数据给用户: Django 模板 仅仅决定如何展现Django视图指定的数据. dd http://blog.csdn.net/pipisorr ...

  2. NodeJS概述

    NodeJS中文API 一.概述 Node.js 是一种建立在Google Chrome’s v8 engine上的 non-blocking (非阻塞), event-driven (基于事件的) ...

  3. nginx 设置client header 的大小与400错误

    nginx默认的header长度上限是4k,如果超过了这个值 如果header头信息请求超过了,nginx会直接返回400错误可以通过以下2个参数来调整nginx的header上限 client_he ...

  4. 【sgu390】数位dp

    这题其实就是不断地合并子树,跟前面例一的思想是一样的. 这个打法我觉得非常优美啊(学别人的),为什么要搞lim1和lim2呢? 是因为在区间lim1~lim2之外的都是没有用的,但是我们f[h][su ...

  5. codevs3304 水果姐逛水果街Ⅰ

    题目描述 Description 水果姐今天心情不错,来到了水果街. 水果街有n家水果店,呈直线结构,编号为1~n,每家店能买水果也能卖水果,并且同一家店卖与买的价格一样. 学过oi的水果姐迅速发现了 ...

  6. centos 下构建lamp环境

    构建准备: 1.配置防火墙,开启80端口.3306端口 vi /etc/sysconfig/iptables -A INPUT -m state --state NEW -m tcp -p tcp - ...

  7. 谈数据中心SDN与NFV

    看到一篇谈论SDN与NFV的文章,分析的还不错,贴过来方便自己后续查阅: http://network.chinabyte.com/175/13095675.shtml 论数据中心SDN与NFV技术关 ...

  8. bzoj 4569 [Scoi2016]萌萌哒 并查集 + ST表

    题目链接 Description 一个长度为\(n\)的大数,用\(S_1S_2S_3...S_n\)表示,其中\(S_i\)表示数的第\(i\)位,\(S_1\)是数的最高位,告诉你一些限制条件,每 ...

  9. git web 服务器的搭建【转】

    转自:http://blog.csdn.net/transformer_han/article/details/6450200 目录(?)[-] git服务器搭建过程 需求 硬件需求一台Ubuntu或 ...

  10. POJ3466(01背包变形)

    Proud Merchants Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others) ...