CEOI2017 One-Way Streets
阿新 • • 發佈:2018-12-17
題目描述
給定一張 個點 條邊的無向圖,現在想要把這張圖定向。
有 個限制條件,每個條件形如 ,表示在新的有向圖當中, 要能夠沿著一些邊走到 。
現在請你求出,每條邊的方向是否能夠唯一確定。同時請給出這些能夠唯一確定的邊的方向。
輸入輸出格式
輸入格式:
第一行兩個空格隔開的正整數 。
接下來 行,每行兩個空格隔開的正整數 ,表示 之間有一條邊。
接下來一行一個整數 ,表示限制條件的個數。
接下來 行,每行兩個空格隔開的正整數 ,描述一個 的限制條件。
輸出格式:
輸出一行一個長度為 的字串,表示每條邊的答案:
若第 條邊必須得要是 指向 的,那麼這個字串的第 個字元應當為 R;
若第 條邊必須得要是 指向 的,那麼這個字串的第 個字元應當為 L;
否則,若第 條邊的方向無法唯一確定,那麼這個字串的第 個字元應當為 B。
思路
可以得到一個的結論:在同一個雙聯通分量中的點之間的邊方向無法確定。
所以可以縮點,然後得到一個森林。
對於要求的方向,多定義一個陣列,對於起點,,終點,。
每一點走向父節點的邊方向可以記住來判斷。
則應由父節點走向子節點
則應由子節點走向父節點
則無法判斷方向。
程式碼
#include<cstdio>
#include<string>
#include<cstring>
#define R_ register
inline int read() {
int ret=0,f=1,ch=getchar();
for (; !isdigit(ch); ch=getchar()) if (ch=='-') f=-f;
for (; isdigit(ch); ch=getchar()) ret=ret*10+ch-48;
return ret*f;
}
const int maxn=2e5+5;
struct edge {int son,nxt,id,s;} E[maxn],T[maxn];
int top,tar,cnt,sta[maxn],dfn[maxn],low[maxn],bel[maxn];
int N,M,P,tot=1,lnk[maxn],hed[maxn],Ans[maxn],vis[maxn],a[maxn];
inline void add_edge(int y,int x,int id) {
E[++tot].son=y,E[tot].nxt=lnk[x],lnk[x]=tot,E[tot].id=id,E[tot].s=+1;
E[++tot].son=x,E[tot].nxt=lnk[y],lnk[y]=tot,E[tot].id=id,E[tot].s=-1;
}
inline void Add_edge(int x,int y,int id,int s) {
T[++tot].son=y,T[tot].nxt=hed[x],hed[x]=tot,T[tot].id=id,T[tot].s=s;
}
void tarjan(int x,int pre=0) {
dfn[x]=low[x]=++cnt,sta[++top]=x;
for (R_ int k=lnk[x],v; v=E[k].son,k; k=E[k].nxt) if (k^pre)
if (!dfn[v]) {
tarjan(v,k^1),low[x]=std::min(low[x],low[v]);
if (low[v]>dfn[x]) {
for (++tar; sta[top]^v; ) bel[sta[top]]=tar,--top;
bel[sta[top]]=tar,--top;
}
} else low[x]=std::min(low[x],dfn[v]);
}
void dfs(int x,int fa,int id,int s) {
for (R_ int k=hed[x],v; v=T[k].son,k; k=T[k].nxt) if (!vis[v])
vis[v]=1,dfs(v,x,T[k].id,T[k].s),a[x]+=a[v];
if (a[x]) Ans[id]=(a[x]*s<0?1:2);
}
int main() {
R_ int i,k,x,y;
for (N=read(),M=read(),i=1; i<=M; ++i) add_edge(read(),read(),i);
for (i=1; i<=N; ++i) if (!dfn[i]) tarjan(i);
if (top) for (++tar; top; --top) bel[sta[top]]=tar;
for (tot=i=1; x=bel[i],i<=N; ++i)
for (k=lnk[i]; y=bel[E[k].son],k; k=E[k].nxt)
if (x^y) Add_edge(x,y,E[k].id,E[k].s);
for (P=read(),i=1; i<=P; ++i) ++a[bel[read()]],--a[bel[read()]];
for (i=1; i<=tar; ++i) if (!vis[i]) vis[i]=1,dfs(i,0,0,0);
for (i=1; i<=M; ++i) putchar(!Ans[i]?'B':(Ans[i]==1?'R':'L'));
return 0;
}