Test instructions
N (2*10^5) point M (2*10^5) edge of the non-directed graph requirements for the direction of the non-directional so that the final directed graph satisfies the Q (2*10^5) instruction each instruction expressed as s->e that is s to e have access to ask whether it is possible
Ideas:
Assuming that there is a circle in the undirected graph, it must also be set into a circle. Therefore, it is easy to analyze the concept of connected components so that only the orientation of the bridge is worth discussing so we can make the edge-connected component of the graph first.
Since the hint in the title may not be connected, the forest
All we have to solve is to put these lines on the tree according to the q instruction (each instruction corresponds to a line on the line tree). If there must be two directions left on the edge of a tree, there is no solution.
The violent placement of the line must be tle. So the idea of a tree segment coverage problem can be solved by tree chain
But the split is still more annoying = = so we use a similar line to cover the "Head Plus tail reduction" method
Define Up[u] means that the edge above the U node is the same as the upward oriented down[u] then if UP[U]&&DOWN[U] the edge must be bidirectional now only need to maintain up and down can be divided into two parts per instruction according to the LCA of S and E. Head plus tail minus "Finally, using the tree DP to find out the point U's up and down from the definition of up and down, you can see Up[u]=up[son (U)]
Code:
#include <cstdio> #include <iostream> #include <cstring> #include <string> #include < algorithm> #include <map> #include <set> #include <vector> #include <queue> #include < cstdlib> #include <ctime> #include <cmath>using namespace std;typedef long long LL; #define N 200010int N, M, q;struct Edge {int u, V, flag, Next,} ed[n << 1];int head[n], Tot;int dfn[n], low[n], IDX, block, sec, Stack[n], Top;int Vis[n], hsh[n], Tree[n];int lca[n][20], Dis[n];int up[n], down[n];void Add (int u, int v) {ed[tot].u = u; ED[TOT].V = v; Ed[tot].flag = 0; Ed[tot].next = Head[u]; Head[u] = tot++;} void Tarjan (int u) {dfn[u] = low[u] = ++idx; Stack[++top] = u; Tree[u] = sec; for (int i = head[u]; ~i; i = ed[i].next) {int v = ED[I].V; if (Ed[i].flag) continue; Ed[i].flag = Ed[i^1].flag = 1; if (dfn[v] = =-1) {Tarjan (v); Low[u] = min (Low[u], low[v]); if (Dfn[u] < LOW[V]) Ed[i].flag = Ed[i^1].flag =-1; } else Low[u] = min (Low[u], dfn[v]); } if (dfn[u] = = Low[u]) {block++; int V; do {v = stack[top--]; HSH[V] = block; } while (U! = v); }}void dfs (int u, int c) {hsh[u] = C; for (int i = head[u]; ~i; i = ed[i].next) {if (Ed[i].flag = =-1) continue; int v = ED[I].V; if (hsh[v] = =-1) Dfs (V, c); }}void init (int u, int from) {Vis[u] = 1; Dis[u] = Dis[from] + 1; Lca[u][0] = from; for (int i = 1; i <; i++) {lca[u][i] = lca[lca[u][i-1]][i-1]; } for (int i = head[u]; ~i; i = ed[i].next) {int v = ED[I].V; if (v! = from) init (V, u); }}int get (int u, int v) {if (Dis[v] > Dis[u]) Swap (U, v); int i, TMP = Dis[u]-DIS[V]; for (i = n; tmp; i--) {if (TMP >= (1 << i)) {tmp-= (1 << i); U = lca[u][i]; }} if (U = = v) return u; for (i = 19; I >= 0; i--) {if (Lca[u][i]! = Lca[v][i]) {u = lca[u][i]; v = lca[v][i]; }} return lca[u][0];} bool OK (int u) {vis[u] = 0; for (int i = head[u]; ~i; i = ed[i].next) {int v = ED[I].V; if (Vis[v]) {if (!ok (v)) return false; Up[u] + = Up[v]; Down[u] + = Down[v]; }} return! (Up[u] && down[u]);} int main () {memset (head,-1, sizeof (head)); scanf ("%d%d%d", &n, &m, &q); for (int i = 1; I <= m; i++) {int u, v; scanf ("%d%d", &u, &v); Add (U, v); Add (V, u); } memset (DFN,-1, sizeof (DFN)); for (int i = 1; I <= n; i++) {if (dfn[i] = = 1) {sec++; Tarjan (i); }} int tmp = tot; tot = 0; Memset (Head,-1, sizeof (head)); for (int i = 0; i < tmp; i++) {if (Ed[i].flag = = 1 && hsh[ed[i].u]! = hsh[ed[i].v]) {Add (H SH[ED[I].U], HSH[ED[I].V]); }} n = Block; for (int i = 1; I <= n; i++) {if (!vis[i]) init (i, i); } bool ans = true; for (int i = 1; I <= Q; i++) {int u, v; scanf ("%d%d", &u, &v); if (tree[u]! = Tree[v]) {puts ("No"); return 0; } u = Hsh[u]; v = hsh[v]; if (U = v) {int fa = get (U, v); up[u]++; up[fa]--; down[v]++; down[fa]--; }} for (int i = 1; I <= n; i++) {if (Vis[i]) {ans = ok (i); if (!ans) break; }} if (ans) puts ("Yes"); Else puts ("No"); return 0;}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Codeforces 555E Case of Computer Network