题意:给定一个有向图,保证无重边自环,求将图中的每条边反向后强联通分量的个数是否会改变。

数据范围:$n$ $≤$ $1e3$,$m$ $≤$ $2e5$。


首先考虑一条边的影响。

因为一条边只能连接两个点,因此将一条边反向至多只能影响它两个端点在强联通分量里的变化,即整体增加一个强联通分量,或整体减少一个强联通分量(或整体不变)。

再考虑将这条边反向之前,两端点 $u$,$v$ 之间的联通情况。

假设这条边为 $u$ $→$ $v$,那么将这条边反向,在图中就可以看作增加一条 $v$ $→$ $u$ 的边,删掉一条 $u$ $→$ $v$ 的边。

那么在删边和添边之前,考虑 $4$ 种情况。

  1. 存在一条 $u$ $→$ $v$ 的路径,且其中不包含 $u$ $→$ $v$ 这条边;存在一条 $v$ $→$ $u$ 的路径;
  2. 存在一条 $u$ $→$ $v$ 的路径,且其中不包含 $u \to v$ 这条边;不存在一条 $v$ $→$ $u$ 的路径;
  3. 不存在不经过 $u$ $→$ $v$ 这条边的一条 $u$ $→$ $v$ 的路径 ;存在一条 $v$ $→$ $u$ 的路径;
  4. 不存在不经过 $u$ $→$ $v$ 这条边的一条 $u$ $→$ $v$ 的路径 ;不存在一条 $v$ $→$ $u$ 的路径;

稍加分析就能得出在整体增加一个强联通分量的时候,是情况 $2$;在整体减少一个强联通分量的时候,是情况 $3$。

原图中是否存在一条 $v \to u$ 的路径只需在原图中爆搜一遍即可。

考虑如何判断是否存在不经过 $u$ $→$ $v$ 这条边的一条 $u$ $→$ $v$ 的路径。

显然一个最暴力的思路就是枚举每条边,打个 $\text{tag}$ 后在图中爆搜,复杂度 $O(m^2)$。

这里复杂度爆炸的原因就是每条边的枚举,因为在图中爆搜是无法避免的,因此把枚举每条边改为枚举每个点 $a$ 试试。

$a$ 不走 $a \to b$ 这条边想要到达 $b$,只需要在不走环的情况下第一条边不走 $a \to b$ 这条边就行了,而若 $a$ 不走 $a \to b$ 这条边,那么相当于 $a$ 可以走除了 $b$ 以外的后继节点。

考虑将问题转化为 $a$ 的后继节点能够被 $a$ 的其他后继节点到达(在不在 $a$ 处走环的情况下,这个可以通过给 $a$ 打个标记等等办法特判)。

当然这个还是需要枚举 $a$ 的出边因此复杂度没有任何改进,进而考虑再将问题转化为 $a$ 的后继节点能够两两到达。

但是这个转化是不对等的,因为后者是前者的充分不必要条件,其实每个点只需要被另 $1$ 个点到达就行了。

这就转换为了一个点集中的点能否被其中的另一个点到达的问题,因此考虑用多源 $\text{bfs}$ 实现,但是因为环的缘故,每个点有可能自己到达自己,因此在被访问的时候要记录一下访问它的点集中的点是谁(这里需要记录两个),同时每个点可以两次入队。

不过由于本人常数过大的缘故,需要使用 $\text{bitset}$ 优化。

code:Submission #34083578 - AtCoder Regular Contest 092

AT ARC092F Two Faced Edges的更多相关文章

  1. @atcoder - ARC092F@ Two Faced Edges

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 给出一个有向图,对每条边都做一次询问: 翻转这条边后,对原图的强 ...

  2. AT3945-[ARC092D]Two Faced Edges【dfs】

    正题 题目链接:https://www.luogu.com.cn/problem/AT3945 题目大意 \(n\)个点\(m\)条边的一张图,对于每条边求它翻转后强连通分量数量是否变化. \(1\l ...

  3. AT3945 [ARC092D] Two Faced Edges

    要求,翻转一条边,强连通分量个数是否会改变. 考虑连通分量个数会改变的因素: 即\(v\to u\)是否成立,以及翻转前,是否有一条\(u \to v\)的路径不经过该条边 以上当只有一个满足时,连通 ...

  4. Atcoder Regular Contest 092 D - Two Faced Edges(图论+bitset 优化)

    Atcoder 题面传送门 & 洛谷题面传送门 orz ymx,ymx ddw %%% 首先既然题目要我们判断强连通分量个数是否改变,我们首先就将原图 SCC 缩个点呗,缩完点后我们很自然地将 ...

  5. Atcoder 乱做

    最近感觉自己思维僵化,啥都不会做了-- ARC103 F Distance Sums 题意 给定第 \(i\) 个点到所有点的距离和 \(D_i\) ,要求构造一棵合法的树.满足第 \(i\) 个点到 ...

  6. 【AtCoder】ARC092

    C - 2D Plane 2N Points 把能连边的点找到然后跑二分图匹配即可 #include <bits/stdc++.h> #define fi first #define se ...

  7. AtCoder Regular Contest 092

    AtCoder Regular Contest 092 C - 2D Plane 2N Points 题意: 二维平面上给了\(2N\)个点,其中\(N\)个是\(A\)类点,\(N\)个是\(B\) ...

  8. AtCoder Regular Contest 092 C D E F

    C - 2D Plane 2N Points 题意 二维平面上有\(N\)个红点,\(N\)个蓝点,一个红点和一个蓝点能配成一对当且仅当\(x_r<x_b\)且\(y_r<y_b\). 问 ...

  9. He faced a maximum sentence of three years.

    Police raided his home in August and found more than 100g of marijuana. He faced a maximum sentence ...

  10. Effective Java Item2:Consider a builder when faced with many constructor parameters

    Item2:Consider a builder when faced with many constructor parameters 当构造方法有多个参数时,可以考虑使用builder方式进行处理 ...

随机推荐

  1. 滚动 Scroller OverScroller

    原文:https://www.baidu.com/link?url=26iKhqGV7w87fqTiCTCwQc3VPcCbedUpAlddWm3uHsEXAGaeH47xY8QCZNGcORGBAU ...

  2. HFS~HTTP File Server 2.4rc2 20191231

    后台,打卡,这有的 电脑 PC   浏览器 打开 安卓平台,浏览器,打开,界面

  3. OpenCv:边缘处理&Canny边缘检测

    卷积边缘: 一.在进行卷积的时候,对于原图像(1,1)的位置,左.上方没有足够的像素做卷积. 二.通常,在卷积之前,在原图增加边缘像素,比如(3*3的,增加一个像素) 三.增加像素值得处理方法,通常有 ...

  4. centos6.5升级python3.6并安装boto3模块

    1.先升级openssl yum安装各种依赖,yum install gcc gcc-c++ autoconf automake zlib zlib-devel pcre-devel tar zxvf ...

  5. 看K线学炒股(0803)

    高位板块的高位个股要回避,即便走反抽行情也要慎重.像容捷股份. 同是房地产行业的荣盛发展和西藏城投,差别怎么这么大?荣盛发展市净率0.4,西藏城投是4.8,市盈率更是一个天上一个地下,但股价呢?所以股 ...

  6. 【FPGA学习】根据datasheet编写Verilog驱动(PCF8574 IO扩展板练习)

    在之间的博客中已经讲了如何阅读一本datasheet并编写Verilog驱动代码,而在这篇博客中就加以应用,为PCF8574 IO扩展板编写驱动并观察效果,至于为什么选择这个,一方面是因为这个芯片功能 ...

  7. YYYY-MM-dd

    Calendar calendar = Calendar.getInstance();  calendar.set(2019, Calendar.DECEMBER, 31); Date strDate ...

  8. kibana启动及导出PDF报错

    kibana启动及导出PDF报错,可能是由于kibana需要的系统依赖没有安装 CentOS/RHEL系统需要安装以下依赖: ipa-gothic-fonts xorg-x11-fonts-100dp ...

  9. curl从入门到精通教程

    直接看英文版 https://catonmat.net/cookbooks/curl

  10. 如何使用C++代码实现1-100之间的素数

    #include "pch.h" #include <iostream> using namespace std; int main() { cout << ...