Atcoder Regular Contest 092 D - Two Faced Edges(图论+bitset 优化)
orz ymx,ymx ddw %%%
首先既然题目要我们判断强连通分量个数是否改变,我们首先就将原图 SCC 缩个点呗,缩完点后我们很自然地将图中的边分为两类:在某个强连通分量中,和不在强连通分量中,我们对这两个情况分别进行讨论。
下面又到了喜闻乐见的找性质的时间了。首先,对于不在同一个强连通分量中的边,把它翻转之后不会影响强连通分量个数,因为这条边不在强连通分量里面,即便把它断掉也不影响强连通分量内部的点的可达性,因此把它翻转只可能接链成环,减少强连通分量个数,而把 \(u\to v\) 翻转后,强连通分量个数减少当且仅当去掉这条边后仍存在 \(u\to v\) 的路径,因为这样会出现 \(u\to v\to u\) 的环。其次,对于在同一个强连通分量中的边,把它翻转之后,本来不能到达的点依然不能到达(证明可考虑反证法,对于两个节点 \(x,y\),如果本来不存在 \(x\to y\),翻转 \(u\to v\) 后就存在了,那么必然是因为存在 \(x\to v\to u\to y\) 的路径,而根据 \(u,v\) 在同一个 SCC 中可知本来就存在 \(v\to u\) 的路径 \(P\)(我们记其为 \(x\xrightarrow{P}y\)),那么必然存在不经过边 \(v\to u\) 的 \(x\to y\) 的路径 \(x\to v\xrightarrow{P}u\to y\),矛盾),而对于原来可以到达的两个点 \(x,y\),如果翻转后 \(x\) 不能到达 \(y\),那必然有 \(x,y\) 在同一个连通分量中,此时连通分量的个数就会改变。我们惊奇地发现,在两种情况中,虽然情况细分起来不一样,但每种情况我们要求的目标是一样的,即去掉某条边 \(u\to v\) 后,\(u\) 是否还能到达 \(v\)。对于 \(u,v\) 在同一个强连通分量中的边 \((u,v)\),如果上述回答为肯定的那么答案即为 same,否则答案为 diff,如果 \(u,v\) 不在同一个强连通分量则反过来。
接下来考虑怎样求这个东西,考虑枚举 \(u\) 并求出以 \(u\) 为起点的所有边的答案,我们将以 \(u\) 为起点的边按照编号(其实不一定要按编号,哪怕 random_shuffle 一下都行,只要钦定一个顺序即可)排序分别为 \(e_1,e_2,\cdots,e_k\),它们的另一个端点分别为 \(v_1,v_2,\cdots,v_k\)。我们从小到大依次枚举这些边并实时维护一个 \(vis_x\) 表示 \(x\) 的可达性,对于某个 \(e_i\),如果我们发现,枚举到 \(e_i\) 时候,已经有 \(vis_{v_i}=1\),那么说明肯定存在一个 \(v_j\) 满足存在 \(u\to v_j\to v_i\) 的路径,即去掉这条边后 \(u\) 还能到达 \(v_i\),否则我们就以 \(v_i\) 为起点 BFS 一遍整张图,找到所有可达的点,注意不能经过 \(u\),否则就无法说明是否经过 \(u\to v_i\) 的边了。(具体实现方法很简单,只需将 \(vis_u\) 设为 \(1\),然后 BFS 所有 \(vis_v\ne 1\) 的点)这样我们只考虑了 \(e_j\) 对 \(e_i\),\(j<i\) 的贡献,因此还需反过来再操作一次,这样即可考虑所有边对 \(v_i\) 的贡献,正确性显然,时间复杂度 \(nm\),可以通过此题,于是这题就做完了。
什么?你说做完了?如果 \(m\) 增大到 \(10^6\) 恐怕你就束手无策了吧……因此我们还需探究复杂度更优的做法,注意到上述做法的瓶颈在于每次 BFS 都枚举了每条边,使得 BFS 的复杂度高达 \(\mathcal O(m)\),事实上,如果当我们 BFS 到某个点 \(u\) 时,只继续 BFS 它的邻居中满足 \(vis_v=0\) 的点 \(v\),这样 BFS 复杂度可以降到 \(\mathcal O(n)\)。那么怎么快速找出这些点呢?注意 \(vis_v\) 的取值只可能是 \(0/1\),因此可以联想到常数巨小无比的……bitset!我们建一个 bitset \(t\),如果 \(vis_v=1\),那么 bitset 上对应位为 \(0\),否则为 \(1\),再对每个点维护它与每个点之间是否有直接边相连,记作 \(has_x\),那么当我们 BFS \(u\) 时,只需遍历 \(has_u\&t\) 上为 \(1\) 的位即可。事实上,bitset 找出所有 \(1\) 的复杂度是 \(\mathcal O(\dfrac{n}{\omega})\) 的,可以这样实现:
for(int y=b._Find_first();y^b.size();y=b._Find_next(y))
于是这题就真的做完了,复杂度 \(\dfrac{n^3}{\omega}+w\),瓶颈在于 bitset 的遍历。
const int MAXN=1e3;
const int MAXM=2e5;
int n,m,hd[MAXN+5],to[MAXM+5],nxt[MAXM+5],ec=0;
int U[MAXM+5],V[MAXM+5];
void adde(int u,int v){to[++ec]=v;nxt[ec]=hd[u];hd[u]=ec;}
bool vis[MAXN+5];
int dfn[MAXN+5],low[MAXN+5],tim=0,bel[MAXN+5],stk[MAXN+5],tp=0,cmp=0;
bitset<MAXN+5> has[MAXN+5];
void tarjan(int x){
dfn[x]=low[x]=++tim;vis[x]=1;stk[++tp]=x;
for(int e=hd[x];e;e=nxt[e]){
int y=to[e];
if(!dfn[y]) tarjan(y),low[x]=min(low[x],low[y]);
else if(vis[y]) low[x]=min(low[x],dfn[y]);
} if(!(dfn[x]^low[x])){
++cmp;int o;do{
o=stk[tp--];vis[o]=0;bel[o]=cmp;
} while(o^x);
}
}
bool can[MAXM+5];
bitset<MAXN+5> alive;
void bfs(int s){
queue<int> q;q.push(s);alive.reset(s);
while(!q.empty()){
int x=q.front();q.pop();bitset<MAXN+5> to=has[x]&alive;
for(int y=to._Find_first();y^to.size();y=to._Find_next(y))
alive.reset(y),q.push(y);
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
scanf("%d%d",&U[i],&V[i]);adde(U[i],V[i]);
has[U[i]].set(V[i]);
}
for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i);
// for(int i=1;i<=n;i++) printf("%d\n",bel[i]);
for(int i=1;i<=n;i++){
alive.set();alive.reset(i);stack<pii> stk;
for(int e=hd[i];e;e=nxt[e]){
stk.push(mp(to[e],e));
if(!alive.test(to[e])){can[e]=1;continue;}
bfs(to[e]);
} alive.set();alive.reset(i);
while(!stk.empty()){
pii x=stk.top();stk.pop();
if(!alive.test(x.fi)){can[x.se]=1;continue;}
bfs(x.fi);
}
}
for(int i=1;i<=m;i++) printf("%s\n",((bel[U[i]]==bel[V[i]])^can[i])?"diff":"same");
return 0;
}
Atcoder Regular Contest 092 D - Two Faced Edges(图论+bitset 优化)的更多相关文章
- AtCoder Regular Contest 092
AtCoder Regular Contest 092 C - 2D Plane 2N Points 题意: 二维平面上给了\(2N\)个点,其中\(N\)个是\(A\)类点,\(N\)个是\(B\) ...
- AtCoder Regular Contest 092 C D E F
C - 2D Plane 2N Points 题意 二维平面上有\(N\)个红点,\(N\)个蓝点,一个红点和一个蓝点能配成一对当且仅当\(x_r<x_b\)且\(y_r<y_b\). 问 ...
- AtCoder Regular Contest 092 C - 2D Plane 2N Points(二分图匹配)
Problem Statement On a two-dimensional plane, there are N red points and N blue points. The coordina ...
- Atcoder Regular Contest 092 A 的改编
原题地址 题目大意 给定平面上的 $n$ 个点 $p_1, \dots, p_n$ .第 $i$ 点的坐标为 $(x_i, y_i)$ .$x_i$ 各不相同,$y_i$ 也各不相同.若两点 $p_i ...
- AtCoder Regular Contest 092 B Two Sequences
题目大意 给定两个长为 $n$ 个整数序列 $a_1, \dots, a_n$ 和 $b_1, \dots, b_n$ .求所有 $a_i + b_j$($1\le i, j\le n$)的 XOR ...
- 思维定势--AtCoder Regular Contest 092 D - Two Sequences
$n \leq 100000$的俩序列,数字范围$2^{28}$,问所有$a_i+b_j$的$n^2$个数字的异或和. 这种东西肯定是按位考虑嘛,从低位开始然后补上进位.比如说第一位俩串分别有$c$个 ...
- AtCoder Regular Contest 092 Two Sequences AtCoder - 3943 (二进制+二分)
Problem Statement You are given two integer sequences, each of length N: a1,…,aN and b1,…,bN. There ...
- AtCoder Regular Contest 092 2D Plane 2N Points AtCoder - 3942 (匈牙利算法)
Problem Statement On a two-dimensional plane, there are N red points and N blue points. The coordina ...
- 【AtCoder Regular Contest 092】C.2D Plane 2N Points【匈牙利算法】
C.2D Plane 2N Points 题意:给定N个红点二维坐标N个蓝点二维坐标,如果红点横纵坐标都比蓝点小,那么它们能够构成一组.问最多能构成多少组. 题解:把满足要求的红蓝点连线,然后就是匈牙 ...
随机推荐
- linux系统(centos)下su和sudo命令的区别
linux系统(centos)下su和sudo命令的区别 区别 我们在日常使用过程中,这2个命令很多时候能达到相同的效果,对细节区别十分模糊,这里进行简单的解释和区分.希望大家能够正确使用这2个命令, ...
- 【数据结构与算法Python版学习笔记】目录索引
引言 算法分析 基本数据结构 概览 栈 stack 队列 Queue 双端队列 Deque 列表 List,链表实现 递归(Recursion) 定义及应用:分形树.谢尔宾斯基三角.汉诺塔.迷宫 优化 ...
- 2021.5.24考试总结 [NOIP模拟3]
带着爆0的心态考的试,没想到整了个假rk2 (炸鱼大佬wtz忒强了OTZ T1 景区路线规划 这题对刚学完概率期望的我来说简直水爆了好吗.. 因为存在时间限制,不好跑高斯消元,就直接跑dp就完了. 令 ...
- 攻防世界 杂项 3.神奇的Modbus
[目标] 了解modbus协议 [工具] Wireshark [分析过程] 在数据包中寻找flag就行,flag是明文形式存储. 工业设备消息传输使用modbus协议.所以我就采集了modbus的通信 ...
- 到底能不能用 join
互联网上一直流传着各大公司的 MySQL 军规,其中关于 join 的描述,有些公司不推荐使用 join,而有些公司则规定有条件的使用 join, 它们都是教条式的规定,也没有详细说其中的原因,这就很 ...
- hdu 1227 Fast Food(DP)
题意: X轴上有N个餐馆.位置分别是D[1]...D[N]. 有K个食物储存点.每一个食物储存点必须和某个餐厅是同一个位置. 计算SUM(Di-(离第i个餐厅最近的储存点位置))的最小值. 1 < ...
- CDP客户数据管理平台体系化搭建
一.Cdp系统简介 1.基本概念 客户数据平台(Customer-Data-Platform),简称CDP:通过采集多方客户数据(主体与线索)等,从而进行精准的客户分析和人群细分,进而实现高效的客户维 ...
- Lambda-让人又爱又恨的“->"
写在前边 聊到Java8新特性,我们第一反应想到的肯定是Lambda表达式和函数式接口的出现.要说ta到底有没有在一定程度上"优化"了代码的简洁性呢?抑或是ta在一定程度上给程序员 ...
- Centos7上安装Ubuntu容器
1.再次之前我们要先装好docker,在上一篇我已经给出了教程,没有安装好的快去看看吧! 2.这里我们使用的是linux系统,所有在线安装是最简便的方法了.我们可以从国内拉取dockerhub镜像,这 ...
- 【编译原理】LL1文法语法分析器
上篇文章[编译原理]语法分析--自上向下分析 分析了LL1语法,文章最后说给出栗子,现在补上去. 说明: 这个语法分析器是利用LL1分析方法实现的. 预测分析表和终结符以及非终结符都是针对一个特定文法 ...