思路:求边双之后因为每个点只会包含在一个边双内,所以给点编号为所在边双的序号,再通过这个进行缩点。
缩点过程中记录新边所对应的原边 e->ori 和无向图中对应的反向边 e->opp,并开 bool 型记录其是否是反向边,然后输入要求的 x,y,记录树上点差分数组 p[x]++,p[y]--,然后进行 dfs 统计答案
dfs 中,对于当前点 x 的子节点 y 及连边 e(x,y)(向下连接的边) 来说,如果 p[y] > 0 则:
p[y] < 0 则与上述情况相反
其余未标记边方向为 B
最后遍历所有原边且为正向的边输出答案
请问思路有问题吗
#pragma GCC target("avx2")
#include <algorithm>
#include <bitset>
#include <cstring>
#include <iostream>
using std::bitset;
using std::cin;
using std::cout;
using std::max;
using std::min;
const char endl = '\n';
const int N = 100500;
struct edge {
edge *nex, *opp;
int fr, to;
bool cut, rev;
char data;
edge* ori;
} graph[N], aft[N];
edge *fir[N], *tot = graph;
void add(int& a, int& b) {
tot->data = 'B';
tot->fr = a;
tot->to = b;
tot->opp = tot + 1;
tot->nex = fir[a];
fir[a] = tot;
++tot;
tot->fr = b;
tot->to = a;
tot->rev = true;
tot->opp = tot - 1;
tot->nex = fir[b];
fir[b] = tot;
++tot;
}
void add(int& a, int& b, edge* e) {
tot->data = 'B';
tot->ori = e;
tot->fr = a;
tot->to = b;
tot->opp = tot + 1;
tot->nex = fir[a];
fir[a] = tot;
++tot;
tot->ori = e->opp;
tot->fr = b;
tot->to = a;
tot->opp = tot - 1;
tot->rev = true;
tot->nex = fir[b];
fir[b] = tot;
++tot;
}
int dfn[N], low[N], tim;
int id[N];
int ecc_cnt;
void tarjan(int nod, edge* edg) {
dfn[nod] = low[nod] = ++tim;
for (edge* e = fir[nod]; e; e = e->nex) {
if (!dfn[e->to]) {
tarjan(e->to, e);
low[nod] = min(low[nod], low[e->to]);
if (low[nod] < low[e->to]) {
e->cut = e->opp->cut = true;
}
} else if (!edg || e != edg->opp) {
low[nod] = min(low[nod], dfn[e->to]);
}
}
}
void add_up(int nod) {
id[nod] = ecc_cnt;
for (edge* e = fir[nod]; e; e = e->nex) {
if (id[e->to] || e->cut) continue;
add_up(e->to);
}
}
int p[N];
void dfs(int nod, int fa) {
int res = 0;
for (edge* e = fir[nod]; e; e = e->nex) {
if (e->to == fa) continue;
dfs(e->to, nod);
if (p[e->to] > 0) {
if (e->rev) {
e->ori->opp->data = 'L';
} else {
e->ori->data = 'R';
}
} else if (p[e->to] < 0) {
if (e->rev) {
e->ori->opp->data = 'R';
} else {
e->ori->data = 'L';
}
}
res += p[e->to];
}
p[nod] += res;
}
void solve() {
std::ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
tot = aft;
memset(fir, 0, sizeof fir);
for (edge* e = graph; e->to; ++e) {
if (!e->rev && id[e->fr] != id[e->to]) add(id[e->fr], id[e->to], e);
}
dfs(1, 0);
for (edge* e = graph; e->to; ++e)
if (!e->rev) cout << e->data;
}
int n, m, t;
int t1, t2;
int main() {
std::ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
cin >> n >> m;
for (int i = 1; i <= m; ++i) {
cin >> t1 >> t2;
add(t1, t2);
}
for (int i = 1; i <= n; ++i)
if (!dfn[i]) tarjan(i, nullptr);
for (int i = 1; i <= n; ++i) {
if (!id[i]) {
++ecc_cnt;
add_up(i);
}
}
// for (int i = 1; i <= n; ++ i) {
// cout << i << ' ' << id[i] << '\n';
// }
cin >> t;
for (int i = 1; i <= t; ++i) {
cin >> t1 >> t2;
++p[id[t1]];
--p[id[t2]];
}
solve();
return 0;
}