考场上看错题,没什么好说的。

然而它就是一个大板子。

发的题解勉强还能看。但是我还想再讲讲。

题目的表述是,如果从A能直接或间接到B,那么就不能同时轰炸A和B。

那么我们从图里随便拽出一条有向路径,从这条路径中随意挑2个点AB,那么要么能从A到B要么从B到A

那么你任意挑出的这两个点只要不是同一个点那么就不能同时轰炸。

带下划线的那一段有什么用呢?它的正确性是显然的。

我所说的“有向路径”没有加任何附加限制,所以可以包括环,环上转几圈就可能出现同一个点呗。

我们考虑单纯的一个环。那么它上的每一个都要单独炸一次。

再考虑单纯的一条路径,那么路径上的每一个点也需要单独炸一次。

如果一个路径进入了一个环,那么这上面的点也必须单独炸一次(路径上的点可以到达环上的任意点)。

如果一个环引出了一个路径,那么环上的点亦可到路径上,都要单独炸一次。

综上,就是要找出一条路径使它上面的不同的点尽量多,不同的点的个数即为答案。

上面那一堆话里已经包括了这个意思:环上的每个点都会给路径长度增加1,且对联通性没有影响。

所以考虑tarjan缩完强联通分量后就没有环了,只不过环变成了权值等于环中点数的一个大点而已

其余普通点的权值为1。现在的问题就变成了在一个DAG里找一条路径使它上面的点权和最大。

不能dfs,因为这是有向的DAG,虽然不是环但也不是树,它可以长得很恶心。

在这个恶心图里面跑dfs就会多次重复地经过3和3下面的点导致大量浪费。

可以倒着搜加个记忆化什么的,然而一个拓扑排序会更方便一些。

 #include<bits/stdc++.h>
using namespace std;
map<int,int>mm;
int n,m,fir[],l[],to[],cnt=,dfn[],low[];
int _fir[],_l[],_to[],_cnt,w[],in[];
int sta[],ins[],tim,top,bl[],cnt_scc,ans,dis[];
int q[],t;
void connect(int a,int b){l[++cnt]=fir[a];fir[a]=cnt;to[cnt]=b;}
void _connect(int a,int b){_l[++_cnt]=_fir[a];_fir[a]=_cnt;_to[_cnt]=b;in[b]++;}
void tarjan(int p){
dfn[p]=low[p]=++tim;sta[++top]=p;ins[p]=;
for(int i=fir[p];i;i=l[i])
if(!dfn[to[i]])tarjan(to[i]),low[p]=min(low[p],low[to[i]]);
else if(ins[to[i]])low[p]=min(low[p],low[to[i]]);
if(dfn[p]==low[p]){
w[++cnt_scc]++;
while(sta[top]!=p)ins[sta[top]]=,bl[sta[top--]]=cnt_scc,w[cnt_scc]++;
top--;bl[p]=cnt_scc;ins[p]=;
}
}
signed main(){
scanf("%d%d",&n,&m);
for(int i=,a,b;i<=m;++i)scanf("%d%d",&a,&b),connect(a,b);
for(int i=;i<=n;++i)if(!dfn[i])tarjan(i);
for(int i=;i<=n;++i)for(int j=fir[i];j;j=l[j])
if(bl[i]!=bl[to[j]])_connect(bl[i],bl[to[j]]);
for(int i=;i<=cnt_scc;++i)if(!in[i])q[++t]=i;
for(int h=;h<=t;++h){
int dt=dis[q[h]]+w[q[h]];ans=max(ans,dt);
for(int i=_fir[q[h]];i;i=_l[i]){
in[_to[i]]--;dis[_to[i]]=max(dis[_to[i]],dt);
if(!in[_to[i]])q[++t]=_to[i];
}
}
printf("%d\n",ans);
}

码量其实也不大

轰炸行动(bomb):tarjan,拓扑排序的更多相关文章

  1. 【bzoj1093】[ZJOI2007]最大半连通子图 Tarjan+拓扑排序+dp

    题目描述 一个有向图G=(V,E)称为半连通的(Semi-Connected),如果满足:对于u,v∈V,满足u→v或v→u,即对于图中任意两点u,v,存在一条u到v的有向路径或者从v到u的有向路径. ...

  2. 【bzoj5017】[Snoi2017]炸弹 线段树优化建图+Tarjan+拓扑排序

    题目描述 在一条直线上有 N 个炸弹,每个炸弹的坐标是 Xi,爆炸半径是 Ri,当一个炸弹爆炸时,如果另一个炸弹所在位置 Xj 满足:  Xi−Ri≤Xj≤Xi+Ri,那么,该炸弹也会被引爆.  现在 ...

  3. 洛谷P1073 Tarjan + 拓扑排序 // 构造分层图

    https://www.luogu.org/problemnew/show/P1073 C国有 n n个大城市和 mm 条道路,每条道路连接这 nn个城市中的某两个城市.任意两个城市之间最多只有一条道 ...

  4. bzoj 1093 最大半连通子图 - Tarjan - 拓扑排序 - 动态规划

    一个有向图G=(V,E)称为半连通的(Semi-Connected),如果满足:?u,v∈V,满足u→v或v→u,即对于图中任意两点u,v,存在一条u到v的有向路径或者从v到u的有向路径.若G'=(V ...

  5. bzoj1093[ZJOI2007]最大半连通子图(tarjan+拓扑排序+dp)

    Description 一个有向图G=(V,E)称为半连通的(Semi-Connected),如果满足:?u,v∈V,满足u→v或v→u,即对于图中任意两点u,v,存在一条u到v的有向路径或者从v到u ...

  6. 【BZOJ2707】[SDOI2012]走迷宫 Tarjan+拓扑排序+高斯消元+期望

    [BZOJ2707][SDOI2012]走迷宫 Description Morenan被困在了一个迷宫里.迷宫可以视为N个点M条边的有向图,其中Morenan处于起点S,迷宫的终点设为T.可惜的是,M ...

  7. 【tarjan 拓扑排序 dp】bzoj1093: [ZJOI2007]最大半连通子图

    思维难度不大,关键考代码实现能力.一些细节还是很妙的. Description 一个有向图G=(V,E)称为半连通的(Semi-Connected),如果满足:?u,v∈V,满足u→v或v→u,即对于 ...

  8. 【Luogu P3387】缩点模板(强连通分量Tarjan&拓扑排序)

    Luogu P3387 强连通分量的定义如下: 有向图强连通分量:在有向图G中,如果两个顶点vi,vj间(vi>vj)有一条从vi到vj的有向路径,同时还有一条从vj到vi的有向路径,则称两个顶 ...

  9. P3387缩点(tarjan+拓扑排序+线性dp)

    题目描述 给定一个 n个点 m 条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大.你只需要求出这个权值和. 允许多次经过一条边或者一个点,但是,重复经过的点,权值只计算一次. 输入 ...

  10. BZOJ 2208 JSOI2010 连通数 Tarjan+拓扑排序

    题目大意:给定一个n个点的有向图,求有多少点对(x,y),使x沿边可到达y 设f[i][j]为从i到j是否可达 首先强联通分量中的随意两个点均可达 于是我们利用Tarjan缩点 缩点之后是一个拓扑图. ...

随机推荐

  1. 快学Scala 第十九课 (trait的abstract override使用)

    trait的abstract override使用: 当我看到abstract override介绍的时候也是一脸懵逼,因为快学scala,只介绍了因为TimestampLogger中调用的super ...

  2. postgres 数据库 citus 集群分片

    前言 什么时候需要考虑做数据切分? 1.能不切分尽量不要切分 并不是所有表都需要进行切分,主要还是看数据的增长速度.切分后会在某种程度上提升业务的复杂度,数据库除了承载数据的存储和查询外,协助业务更好 ...

  3. vue运行报错webpack-dev-server: command not found

    翻译过来就是: 'webpack-dev-server' 不是内部或外部命令,也不是可运行的程序 解决方法: 然后总结下成功的步骤: 1. 直接在项目目录下: cnpm install npm run ...

  4. 【RocketMQ源码学习】- 1. 入门

    为什么读RocketMQ 消息队列在互联网应用中使用较为广泛,学习她可以让我门更加了解使用技术的工作原理 透过学习她的源码,拓宽认知 RocketMQ经历了阿里双十一 有哪些名词 Producer 消 ...

  5. 算法学习之剑指offer(一)

    题目一: 题目描述 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 思路1:遍历 ...

  6. VPGAME 的 Kubernetes 迁移实践

    作者 | 伍冲斌  VPGAME 运维开发工程师 导读:VPGAME 是集赛事运营.媒体资讯.大数据分析.玩家社群.游戏周边等为一体的综合电竞服务平台.总部位于中国杭州,在上海和美国西雅图分别设立了电 ...

  7. 像智能手机一样管理云端应用:阿里云联合微软全球首发开放应用模型(OAM)

    2019 年 10 月 17 日上午 9 点 15 分,阿里巴巴合伙人.阿里云智能基础产品事业部总经理蒋江伟在 QCon 上海<基于云架构的研发模式演进>主题演讲中,正式宣布: " ...

  8. JavaScript ES6函数式编程(二):柯里化、偏应用和组合、管道

    上一篇介绍了闭包和高阶函数,这是函数式编程的基础核心.这一篇来看看高阶函数的实战场景. 首先强调两点: 注意闭包的生成位置,清楚作用域链,知道闭包生成后缓存了哪些变量 高阶函数思想:以变量作用域作为根 ...

  9. Hydra爆破神器使用

    参数详解: -R 根据上一次进度继续破解-S 使用SSL协议连接-s 指定端口-l 指定用户名-L 指定用户名字典(文件)-p 指定密码破解-P 指定密码字典(文件)-e 空密码探测和指定用户密码探测 ...

  10. metasploit(MSF)渗透平台命令大全

    转自互联网 记录以备后用 show exploits 列出metasploit框架中的所有渗透攻击模块. show payloads 列出metasploit框架中的所有攻击载荷. show auxi ...