题目描述
给定一张 n 个点 m 条边的无向图,现在想要把这张图定向。 有 p 个限制条件,每个条件形如(xi,yi)(xi,yi),表示在新的有向图当中,xixi要能够沿着一些边走到 yiyi。 现在请你求出,每条边的方向是否能够唯一确定。同时请给出这些能够唯一确定的边的方向。
输入格式
第一行两个空格隔开的正整数 n,m。 接下来 m 行,每行两个空格隔开的正整数ai,biai,bi,表示 ai,biai,bi之间有一条边。 接下来一行一个整数 p表示限制条件的个数。 接下来 p 行,每行两个空格隔开的正整数 xi,yixi,yi,描述一个(xi,yi)(xi,yi)的限制条件。
输出格式
输出一行一个长度为 m 的字符串,表示每条边的答案:
若第 i 条边必须得要是 aiai指向 bibi 的,那么这个字符串的第i个字符应当为 R;
若第 i 条边必须得要是bibi 指向 aiai 的,那么这个字符串的第i个字符应当为 L;
否则,若第 i 条边的方向无法唯一确定,那么这个字符串的第i个字符应当为 B。样例数据
input
5 6
1 2
1 2
4 3
2 3
1 3
5 1
2
4 5
1 3
output
BBRBBL
数据规模与约定
对于所有测试点,有1≤n,m,p≤100 000;1≤ai,bi,xi,yi≤n1≤n,m,p≤100000;1≤ai,bi,xi,yi≤n1≤n,m,p≤100 000;1≤ai,bi,xi,yi≤n1≤n,m,p≤100000;1≤ai,bi,xi,yi≤n。
子任务1(30%):有n,m≤1000;p≤100子任务1(30%):有n,m≤1000;p≤100;
子任务2(30%):有p≤100子任务2(30%):有p≤100;
子任务3(40%):无特殊限制子任务3(40%):无特殊限制。
时间限制:1s1s
空间限制:256MB256MB
边双缩点后查分
#include
using namespace std;
#define rep(i,j,k) for(int i = j;i <= k;++i)
#define repp(i,j,k) for(int i = j;i >= k;--i)
#define ll long long
namespace io {
const int SIZE = (1 << 21) + 1;
char ibuf[SIZE], *iS, *iT, obuf[SIZE], *oS = obuf, *oT = oS + SIZE - 1, c, qu[55]; int f, qr;
// getchar
#define gc() (iS == iT ? (iT = (iS = ibuf) + fread (ibuf, 1, SIZE, stdin), (iS == iT ? EOF : *iS ++)) : *iS ++)
// print the remaining part
inline void flush () {
fwrite (obuf, 1, oS - obuf, stdout);
oS = obuf;
}
// putchar
inline void putc (char x) {
*oS ++ = x;
if (oS == oT) flush ();
}
// input a signed integer
template <class I>
inline void gi (I &x) {
for (f = 1, c = gc(); c < '0' || c > '9'; c = gc()) if (c == '-') f = -1;
for (x = 0; c <= '9' && c >= '0'; c = gc()) x = x * 10 + (c & 15); x *= f;
}
// print a signed integer
template <class I>
inline void print (I &x) {
if (!x) putc ('0'); if (x < 0) putc ('-'), x = -x;
while (x) qu[++ qr] = x % 10 + '0', x /= 10;
while (qr) putc (qu[qr --]);
}
//no need to call flush at the end manually!
struct Flusher_ {~Flusher_(){flush();}}io_flusher_;
}
using io :: gi;
using io :: putc;
using io :: print;
int n,m,Q;
int linkk[101000],t;
int dfn[101000],low[101000],tot;
int bel[101000],f[101000][21],dep[101000];
int bz1[101000],bz2[101000],out[101000];
bool inq[101000],vis[101000];
stack<int>st;
struct node{int n,y,id;}e[201000];
struct linei{int l,r;}q[101000];
inline int min(int a,int b){return a<b?a:b;}
void insert(int x,int y,int id){
e[++t].y = y;e[t].n = linkk[x];e[t].id = id;linkk[x] = t;
e[++t].y = x;e[t].n = linkk[y];e[t].id = id;linkk[y] = t;
}
void tarjan(int x,int fa){
dfn[x] = low[x] = ++tot;st.push(x);inq[x] = true;
for(int i = linkk[x];i;i = e[i].n) if((i^1) != fa){
int y = e[i].y;
if(!dfn[y]) {
tarjan(y,i);
low[x] = min(low[x],low[y]);
}
else if(inq[y]) low[x] = min(low[x],dfn[y]);
}
if(dfn[x] == low[x]){
bel[0]++;
while(st.top() != x){
inq[st.top()] = false;
bel[st.top()] = bel[0];
st.pop();
}
inq[x] = false; bel[x] = bel[0]; st.pop();
}
}
void init(){
int x,y;t=1;
gi(n); gi(m);
rep(i,1,m) gi(x),gi(y) ,insert(x,y,i),q[i].l = x,q[i].r = y;
}
void dfs(int x,int fa){
vis[x] = true;
f[x][0] = fa; dep[x] = dep[fa]+1;
rep(j,1,20) f[x][j] = f[f[x][j-1]][j-1];
for(int i = linkk[x];i;i = e[i].n) if(e[i].y != fa && !vis[e[i].y]) dfs(e[i].y,x);
}
int lca(int x,int y){
if(dep[x] < dep[y]) swap(x,y);
repp(j,20,0) if(dep[f[x][j]] >= dep[y]) x = f[x][j];
if(x == y) return x;
repp(j,20,0) if(f[x][j] != f[y][j]) x = f[x][j],y = f[y][j];
return f[x][0];
}
void dfs(int x){
vis[x] = true;
bool flag = true;
for(int i = linkk[x];i;i = e[i].n) if(e[i].y != f[x][0]){
int y = e[i].y;
if(!vis[y]) dfs(y),flag = false;
if(bz1[y] > 0) out[e[i].id] = (i&1) ? 1 : 2;
if(bz2[y] > 0) out[e[i].id] = (i&1) ? 2 : 1;
if(!flag) bz1[x] += bz1[y] , bz2[x] += bz2[y];
}
}
int main(){
init();
rep(i,1,n) if(!dfn[i]) tarjan(i,0);
memset(linkk,0,sizeof(linkk)); t = 1;
rep(i,1,m) if(bel[q[i].l] != bel[q[i].r]) insert(bel[q[i].l],bel[q[i].r],i);
rep(i,1,bel[0]) if(!vis[i]) dfs(i,0);
gi(Q); int x,y,z;
rep(i,1,Q){
gi(x); gi(y); x = bel[x];y = bel[y]; if(x == y) continue; z = lca(x,y);
bz1[x]++;bz1[z]--; bz2[y]++;bz2[z]--;
}
memset(vis,0,sizeof(vis));
rep(i,1,bel[0]) if(!vis[i]) dfs(i);
rep(i,1,m) if(out[i] == 0) printf("%c",'B');
else if(out[i] == 1) printf("%c",'R');
else if(out[i] == 2) printf("%c",'L');
return 0;
}