\(\mathcal{Description}\)

  Link.

  给定 \(n\) 个点 \(m\) 条边的无向图,判断是否有给每条边定向的方案,使得 \(q\) 组有序点对 \((s,t)\) 都有 \(s\) 可达 \(t\)。

  \(n,m,q\le2\times10^5\)。

\(\mathcal{Solution}\)

  首先,对于原图中的边双,显然是可以让它们互相可达的,考虑把边双缩点。

  此后,图变成了一片森林。单独考虑一棵树,从 \(s\) 到 \(t\) 的有向路径相当于规定了某些点连向父亲的边的方向。所以树上差分,在根上记录点对进入 / 走出子树的次数。若某个棵子树既有进入又有走出就肯定不合法啦。

\(\mathcal{Code}\)

#include <cstdio>
#include <cstdlib>
#include <assert.h> #define adj( g, u, v ) \
for ( int i = g.head[u], v; v = g.to[i], i; i = g.nxt[i] ) #define NO() ( puts ( "NO" ), exit ( 0 ) ) const int MAXN = 2e5;
int n, m, q;
int dfc, dfn[MAXN + 5], low[MAXN + 5];
int cnt, bel[MAXN + 5], part, color[MAXN + 5];
int dep[MAXN + 5], fa[MAXN + 5][20], in[MAXN + 5], out[MAXN + 5];
bool cut[MAXN + 5], vis[MAXN + 5], chk[MAXN + 5]; struct Graph {
int ecnt, head[MAXN + 5], to[MAXN * 2 + 5], nxt[MAXN * 2 + 5];
Graph (): ecnt ( 1 ) {}
inline void link ( const int s, const int t ) {
to[++ ecnt] = t, nxt[ecnt] = head[s];
head[s] = ecnt;
}
} G, T; inline void chkmin ( int& a, const int b ) { if ( b < a ) a = b; } inline int rint () {
int x = 0; char s = getchar ();
for ( ; s < '0' || '9' < s; s = getchar () );
for ( ; '0' <= s && s <= '9'; s = getchar () ) x = x * 10 + ( s ^ '0' );
return x;
} inline void Tarjan ( const int u, const int id ) {
dfn[u] = low[u] = ++ dfc;
adj ( G, u, v ) {
if ( ! dfn[v] ) {
Tarjan ( v, i ), chkmin ( low[u], low[v] );
if ( low[v] > dfn[u] ) cut[i >> 1] = true;
} else if ( i ^ id ^ 1 ) chkmin ( low[u], dfn[v] );
}
} inline void mark ( const int u, const int col ) {
bel[u] = col, vis[u] = true;
adj ( G, u, v ) {
if ( ! cut[i >> 1] && ! vis[v] ) {
mark ( v, col );
}
}
} inline void init ( const int u, const int f, const int c ) {
color[u] = c, dep[u] = dep[fa[u][0] = f] + 1;
for ( int i = 1; fa[u][i - 1]; ++ i ) fa[u][i] = fa[fa[u][i - 1]][i - 1];
adj ( T, u, v ) if ( v ^ f ) init ( v, u, c );
} inline int calcLCA ( int u, int v ) {
assert ( color[u] == color[v] );
if ( dep[u] < dep[v] ) u ^= v ^= u ^= v;
for ( int i = 17; ~ i; -- i ) if ( dep[fa[u][i]] >= dep[v] ) u = fa[u][i];
if ( u == v ) return u;
for ( int i = 17; ~ i; -- i ) if ( fa[u][i] ^ fa[v][i] ) u = fa[u][i], v = fa[v][i];
return fa[u][0];
} inline void check ( const int u, const int f ) {
chk[u] = true;
adj ( T, u, v ) if ( v ^ f ) {
check ( v, u );
if ( in[v] && out[v] ) NO ();
in[u] += in[v], out[u] += out[v];
}
} int main () {
n = rint (), m = rint (), q = rint ();
for ( int i = 1, u, v; i <= m; ++ i ) {
u = rint (), v = rint ();
G.link ( u, v ), G.link ( v, u );
}
for ( int i = 1; i <= n; ++ i ) if ( ! dfn[i] ) Tarjan ( i, -1 );
for ( int i = 1; i <= n; ++ i ) if ( ! vis[i] ) mark ( i, ++ cnt );
for ( int u = 1; u <= n; ++ u ) {
adj ( G, u, v ) if ( cut[i >> 1] ) {
T.link ( bel[u], bel[v] );
}
}
for ( int i = 1; i <= cnt; ++ i ) if ( ! color[i] ) init ( i, 0, ++ part );
for ( int i = 1, s, t; i <= q; ++ i ) {
s = bel[rint ()], t = bel[rint ()];
if ( s == t ) continue;
if ( color[s] ^ color[t] ) NO ();
int w = calcLCA ( s, t );
++ out[s], -- out[w], ++ in[t], -- in[w];
}
for ( int i = 1; i <= n; ++ i ) if ( ! chk[i] ) check ( i, 0 );
puts ( "YES" );
return 0;
}

Solution -「CF 555E」Case of Computer Network的更多相关文章

  1. 「CF555E」 Case of Computer Network

    「CF555E」 Case of Computer Network 传送门 又是给边定向的题目(马上想到欧拉回路) 然而这个题没有对度数的限制,你想歪了. 然后又开始想一个类似于匈牙利的算法:我先跑, ...

  2. Solution -「CF 1342E」Placing Rooks

    \(\mathcal{Description}\)   Link.   在一个 \(n\times n\) 的国际象棋棋盘上摆 \(n\) 个车,求满足: 所有格子都可以被攻击到. 恰好存在 \(k\ ...

  3. Solution -「CF 917D」Stranger Trees

    \(\mathcal{Description}\)   Link.   给定一棵包含 \(n\) 个点的有标号树,求与这棵树重合恰好 \(0,1,\cdots,n-1\) 条边的树的个数,对 \(10 ...

  4. Solution -「CF 908G」New Year and Original Order

    \(\mathcal{Description}\)   Link.   对于 \(x\in\mathbb N^*\),令 \(s(x)\) 表示将 \(x\) 十进制下的各位数码排序后得到的十进制数的 ...

  5. Solution -「CF 1622F」Quadratic Set

    \(\mathscr{Description}\)   Link.   求 \(S\subseteq\{1,2,\dots,n\}\),使得 \(\prod_{i\in S}i\) 是完全平方数,并最 ...

  6. Solution -「CF 923F」Public Service

    \(\mathscr{Description}\)   Link.   给定两棵含 \(n\) 个结点的树 \(T_1=(V_1,E_1),T_2=(V_2,E_2)\),求一个双射 \(\varph ...

  7. Solution -「CF 923E」Perpetual Subtraction

    \(\mathcal{Description}\)   Link.   有一个整数 \(x\in[0,n]\),初始时以 \(p_i\) 的概率取值 \(i\).进行 \(m\) 轮变换,每次均匀随机 ...

  8. Solution -「CF 1586F」Defender of Childhood Dreams

    \(\mathcal{Description}\)   Link.   定义有向图 \(G=(V,E)\),\(|V|=n\),\(\lang u,v\rang \in E \Leftrightarr ...

  9. Solution -「CF 1237E」Balanced Binary Search Trees

    \(\mathcal{Description}\)   Link.   定义棵点权为 \(1\sim n\) 的二叉搜索树 \(T\) 是 好树,当且仅当: 除去最深的所有叶子后,\(T\) 是满的: ...

随机推荐

  1. HTTP 408 问题 - Koa body parser

    环境描述: 1.nodejs 作为 api 服务器,转发请求给 nginx 2.用 curl 测试,返回 408 找了很久没有找到原因,发现了一篇文章: https://lujunda.cn/2016 ...

  2. 第10组 Beta冲刺 (5/5)(组长)

    1.1基本情况 ·队名:今晚不睡觉 ·组长博客:https://www.cnblogs.com/cpandbb/p/14018671.html ·作业博客:https://edu.cnblogs.co ...

  3. Hystrix的原理与架构

    一.定义 一个开源的延迟与容错框架,用于隔离访问远程服务.第三记库,防止出现级联失败 当某个或某些服务反应慢或者超时严重,主动熔断,当情况好转后,可以自动重连 策略:服务降级.服务限流.服务熔断.服务 ...

  4. 服务器表单字符串转化Vue表单挂在到对应DOM节点

    今天在项目开发中,遇到从后端返回的vue文件(包含template,js,css)的文件,试过用v-html解析文件,渲染到页面,但是无法渲染,后来去查了一堆资料,自己写了一个全局方法来解析这类文件 ...

  5. sql解除死锁

    select spIdfrom master..SysProcesseswhere db_Name(dbID) = 'Tb_axxxxx'and spId <> @@SpIdand dbI ...

  6. STC8H开发(六): SPI驱动ADXL345三轴加速度检测模块

    目录 STC8H开发(一): 在Keil5中配置和使用FwLib_STC8封装库(图文详解) STC8H开发(二): 在Linux VSCode中配置和使用FwLib_STC8封装库(图文详解) ST ...

  7. Win7升级Win11升级记录及教程 【错误码(0×8004242d)】

    hellow,大家好,我是公众号棱镜Prism K的[K君].家中电脑因为一些原因不得不进行升级,下面是我对这次电脑升级所进行的记录. step 1.打开微软官网,找到对应的WIN11下载模块,这里注 ...

  8. JDK并发工具类

    在JDK的并发包里提供了几个非常有用的并发工具类.CountDownLatch.CyclicBarrier和Semaphore工具类提供了一种并发流程控制的手段,Exchanger工具类则提供了在线程 ...

  9. gin框架中的路由

    基本路由 gin框架中采用的路由库是基于httrouter做的 地址为:https://github.com/julienschmidt/httprouter httprouter路由库 点击查看代码 ...

  10. K8s 资源范围管理对象 LimitRange

    默认情况下如果创建一个 Pod 没有设置 Limits 和 Requests 对其加以限制,那么这个 Pod 可能能够使用 Kubernetes 集群中全部资源, 但是每创建 Pod 资源时都加上这个 ...