is to compare the water of the e-question, I think I want to write a write incredibly 1 a
For this problem, we can easily think of a side pair of the original image, after the direction of any two points must be up to
Then we can find the edges of the original image and double-indent each side into a single point.
Then the original image becomes a non-circular graph, that is, a forest
We then consider each task:
1, if s and T are in a side double, it is obviously feasible
2, if s and T are in two trees, obviously not connected is not feasible
3, S and T are in a tree, then all sides of the s->lca are upward, and all sides of the lca->t are downward.
For the third case, we can make an up mark on S and a down mark on t
Then the up and down clearance will be delivered over the LCA.
So at the end of the day, we just need to do the forest. Dfs can determine viability
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include < Cstdlib> #include <stack>using namespace std;const int maxn=200010;int n,m,q;int u,v;struct edge{int u,v;} C[maxn];int h[maxn],cnt=1;struct edge{int To,next;} G[maxn<<2];int pre[maxn],low[maxn];int dfs_clock=0,bcc_cnt=0;int bccno[maxn],f[maxn];int fa[maxn],anc[maxn][ 20];int dep[maxn];int up[maxn],down[maxn];stack<int>s;int ufs (int x) {return f[x]==x?x:f[x]=ufs (f[x]);} void Add (int x,int y) {++cnt; G[cnt].to=y; g[cnt].next=h[x];h[x]=cnt;} void DFS (int u,int f) {pre[u]=low[u]=++dfs_clock; S.push (U), for (int i=h[u];i;i=g[i].next) {if (i== (f^1)) Continue;int v=g[i].to;if (!pre[v]) {DFS (v,i); Low[u]=min (low[u ],LOW[V]);} else if (!bccno[v]) low[u]=min (Low[u],pre[v]);} if (Low[u]==pre[u]) {bcc_cnt++;for (;;) {int now=s.top (); S.pop (); bccno[now]=bcc_cnt;if (now==u) break;}} return;} void Get_tree () {for (int i=1;i<=n;++i) {if (!pre[i]) DFS (i,0);} return;} void Get_dfs (int u,int f) {fa[u]=f;for (int i=h[u];I;i=g[i].next) {int v=g[i].to;if (v==f) continue;dep[v]=dep[u]+1; Get_dfs (v,u);} return;} void Pre_lca () {for (int i=1;i<=n;++i) {anc[i][0]=fa[i];for (int j=1; (1<<j) <=n;++j) anc[i][j]=-1;} for (int j=1, (1<<j) <=n;++j) {for (int i=1;i<=n;++i) {if (anc[i][j-1]!=-1) {int a=anc[i][j-1];anc[i][j]=anc[ A][J-1];}}} return;} int LCA (int p,int q) {if (Dep[p]<dep[q]) swap (P,Q); int log;for (log=0; (1<<log) <=dep[p];++log); Log--;for ( int i=log;i>=0;--i) {if (dep[p]-(1<<i) >=dep[q]) p=anc[p][i];} if (p==q) return p;for (int i=log;i>=0;--i) {if (Anc[p][i]!=-1&&anc[p][i]!=anc[q][i]) {P=anc[p][i];q=anc[q] [i];}} return fa[p];} void check (int u,int f) {for (int i=h[u];i;i=g[i].next) {int v=g[i].to;if (v==f) Continue;check (v,u); Up[u]+=up[v];d own[u ]+=DOWN[V];} if (up[u]>0&&down[u]>0) {printf ("no\n"); exit (0);} return;} int main () {scanf ("%d%d%d", &n,&m,&q), for (int i=1;i<=m;++i) {scanf ("%d%d", &C[I].U,&C[I].V); Add (C[I].U,C[I].V); add (c[i].v,c[i].u);} Get_tree (); Memset (h, 0,sizeof (h)); cnt=1;for (int i=1;i<=n;++i) f[i]=i;for (int i=1;i<=m;++i) {int A=bccno[c[i].u];int b=bccno[c[i].v ];if (a!=b) {Add (b); add (b,a); int D1=ufs (a), D2=ufs (b.); if (D1!=D2) f[d1]=d2;} for (int i=1;i<=bcc_cnt;++i) {int rt=ufs (i); if (rt==i) Get_dfs (rt,-1);} Pre_lca (); for (int i=1;i<=q;++i) {scanf ("%d%d", &u,&v); int a=bccno[u],b=bccno[v];if (UFS (a)!=ufs (b)) { printf ("no\n"); return 0;} int Lca=lca (A, b); up[a]++;d own[b]++;up[lca]--;d own[lca]--;} for (int i=1;i<=bcc_cnt;++i) {int rt=ufs (i); if (rt==i) check (rt,-1);} printf ("yes\n"); return 0;}
Codeforces #310 Div1 E