轰炸行动(bomb):tarjan,拓扑排序
考场上看错题,没什么好说的。
然而它就是一个大板子。
发的题解勉强还能看。但是我还想再讲讲。
题目的表述是,如果从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,拓扑排序的更多相关文章
- 【bzoj1093】[ZJOI2007]最大半连通子图 Tarjan+拓扑排序+dp
题目描述 一个有向图G=(V,E)称为半连通的(Semi-Connected),如果满足:对于u,v∈V,满足u→v或v→u,即对于图中任意两点u,v,存在一条u到v的有向路径或者从v到u的有向路径. ...
- 【bzoj5017】[Snoi2017]炸弹 线段树优化建图+Tarjan+拓扑排序
题目描述 在一条直线上有 N 个炸弹,每个炸弹的坐标是 Xi,爆炸半径是 Ri,当一个炸弹爆炸时,如果另一个炸弹所在位置 Xj 满足: Xi−Ri≤Xj≤Xi+Ri,那么,该炸弹也会被引爆. 现在 ...
- 洛谷P1073 Tarjan + 拓扑排序 // 构造分层图
https://www.luogu.org/problemnew/show/P1073 C国有 n n个大城市和 mm 条道路,每条道路连接这 nn个城市中的某两个城市.任意两个城市之间最多只有一条道 ...
- bzoj 1093 最大半连通子图 - Tarjan - 拓扑排序 - 动态规划
一个有向图G=(V,E)称为半连通的(Semi-Connected),如果满足:?u,v∈V,满足u→v或v→u,即对于图中任意两点u,v,存在一条u到v的有向路径或者从v到u的有向路径.若G'=(V ...
- bzoj1093[ZJOI2007]最大半连通子图(tarjan+拓扑排序+dp)
Description 一个有向图G=(V,E)称为半连通的(Semi-Connected),如果满足:?u,v∈V,满足u→v或v→u,即对于图中任意两点u,v,存在一条u到v的有向路径或者从v到u ...
- 【BZOJ2707】[SDOI2012]走迷宫 Tarjan+拓扑排序+高斯消元+期望
[BZOJ2707][SDOI2012]走迷宫 Description Morenan被困在了一个迷宫里.迷宫可以视为N个点M条边的有向图,其中Morenan处于起点S,迷宫的终点设为T.可惜的是,M ...
- 【tarjan 拓扑排序 dp】bzoj1093: [ZJOI2007]最大半连通子图
思维难度不大,关键考代码实现能力.一些细节还是很妙的. Description 一个有向图G=(V,E)称为半连通的(Semi-Connected),如果满足:?u,v∈V,满足u→v或v→u,即对于 ...
- 【Luogu P3387】缩点模板(强连通分量Tarjan&拓扑排序)
Luogu P3387 强连通分量的定义如下: 有向图强连通分量:在有向图G中,如果两个顶点vi,vj间(vi>vj)有一条从vi到vj的有向路径,同时还有一条从vj到vi的有向路径,则称两个顶 ...
- P3387缩点(tarjan+拓扑排序+线性dp)
题目描述 给定一个 n个点 m 条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大.你只需要求出这个权值和. 允许多次经过一条边或者一个点,但是,重复经过的点,权值只计算一次. 输入 ...
- BZOJ 2208 JSOI2010 连通数 Tarjan+拓扑排序
题目大意:给定一个n个点的有向图,求有多少点对(x,y),使x沿边可到达y 设f[i][j]为从i到j是否可达 首先强联通分量中的随意两个点均可达 于是我们利用Tarjan缩点 缩点之后是一个拓扑图. ...
随机推荐
- Java 学习笔记之 异常法停止线程
异常法停止线程: public class RealInterruptThread extends Thread { @Override public void run() { try { for ( ...
- Kafka 学习笔记之 Kafka0.11之console-producer/console-consumer
Kafka 学习笔记之 Kafka0.11之console-producer/console-consumer: 启动Zookeeper 启动Kafka0.11 创建一个新的Topic: ./kafk ...
- IDEA 学习笔记之 Spark/SBT项目开发
Spark/SBT项目开发: 下载Scala SDK 下载SBT 配置IDEA SBT:(如果不配置,就会重新下载SBT, 非常慢,因为以前我已经下过了,所以要配置为过去使用的SBT) 新建立SBT项 ...
- 用js做数字字母混合的随机四位验证码
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- 你真的懂Spring Java Config 吗?Full @Configuration vs lite @Bean mode
Full @Configuration和lite @Bean mode 是 Spring Java Config 中两个非常有意思的概念. 先来看一下官方文档关于这两者的相关内容: The @Bean ...
- CSS实现带箭头的提示框
我们在很多UI框架中看到带箭头的提示框,感觉挺漂亮,但是之前一直不知道其原理,今天网上找了些资料算是弄清楚原理了: 先上效果图: 原理分析: 上面的箭头有没有觉得很像一个三角形,是的,它就是三角形:只 ...
- JAVA之类的动手动脑
1.默认构造方法与自定义的构造方法的冲突 package com.xu; class fool { int value; fool(int nowvalue) { value=nowvalue; } ...
- C语言基于窗体命令行打包,解包和浏览程序
#include<stdio.h>#include<stdlib.h>#include<string.h>#include<windows.h>#inc ...
- Io流的概述
Io流的概述IO: I输入(Input),O 输出(Output)1.什么是IO流? 数据流,IO是严格的“水流模型” 所以IO流是用来读写数据,或者传输数据. 注意:File只能操作文件对象本身,而 ...
- php服务器有哪些
服务器按照功能可以分为:文件服务器.数据库服务器.web服务器.邮件服务器.代理服务器..... 而上述所有的服务器,均可以用php做开发,比如说做web服务器,常用的构架是php+Mysql+Apa ...