[CSP-S模拟测试]:轰炸行动(bomb)(塔尖+拓扑排序+语文)
题目描述
战狂也在玩《魔方王国》。他只会征兵而不会建城市,因此他决定对小奇的城市进行轰炸。
小奇有n座城市,城市之间建立了$m$条有向的地下通道。战狂会发起若干轮轰炸,每轮可以轰炸任意多个城市。
每座城市里都有战狂部署的间谍,在城市遭遇轰炸时,它们会通过地下通道撤离至其它城市。非常不幸的是,在地道里无法得知其它城市是否被轰炸,如果存在两个不同的城市$i$,$j$,它们在同一轮被轰炸,并且可以通过地道从城市$i$到达城市$j$,那么城市$i$的间谍可能因为撤离到城市$j$而被炸死。为了避免这一情况,战狂不会在同一轮轰炸城市$i$和城市$j$。
你需要求出战狂最少需要多少轮可以对每座城市都进行至少一次轰炸。
输入格式
第一行两个整数$n$,$m$。接下来$m$行每行两个整数$a$,$b$表示一条从$a$连向$b$的单向边。
输出格式
一行一个整数表示答案。
样例
样例输入1:
5 4
1 2
2 3
3 1
4 5
样例输出1:
3
样例输入2:
10 10
3 4
5 4
7 1
6 5
6 4
7 4
1 7
5 8
1 2
9 10
样例输出2:
3
数据范围与提示
对于20%的数据,$n,m\leqslant 10$。
对于40%的数据,$n,m\leqslant 1,000$。
对于另外30%的数据,保证无环。
对于100%的数据,$n,m\leqslant 1,000,000$。
题解
这显然是一道语文题,那么我先来解释一下题意。
这道题所说的不能同时炸的两座城市当且仅当城市$i$能到达城市$j$,或城市$j$能到达城市$i$,而不是说城市$i$有一条边能直接指向城市$j$,反之同理。
如下图中,点$1$虽不能直接到达点$4$和$5$,但是可以通过点$2$间接到达点$4$和$5$,所以这张图需要炸$5$次,而不是$3$次。
回归到这道题,首先,你可能会想到拓扑排序,用拓扑排序分层,一共有几层就需要炸几次。
那么问题来了,这道题会出现有环的情况,当然是塔尖啦,可以知道,一个环只能一个一个炸,不可能有两个可以一起炸,那么我们在缩环的时候记录一下环的大小即可。
题是简单题,语文不好才是硬伤。
再次印证了那句话:得语文者得$OI$,得语文者得天下!
时间复杂度:$\Theta(n+m)$。
期望的分:$100$分。
实际的分:$100$分。
代码时刻
#include<bits/stdc++.h>
using namespace std;
struct rec
{
int nxt;
int to;
}e[2000001],wzc[20000001];
int head[1000001],headw[1000001],cnt,cntw;
int n,m;
int dfn[1000001],low[1000001],sta[1000001],ins[1000001],c[1000001],d[1000001],size[1000001],num,top,tot;
queue<pair<int,int> > q;
int ans;
void add(int x,int y)
{
e[++cnt].nxt=head[x];
e[cnt].to=y;
head[x]=cnt;
}
void add_w(int x,int y)
{
wzc[++cntw].nxt=headw[x];
wzc[cntw].to=y;
headw[x]=cntw;
}
void tarjan(int x)//缩点
{
dfn[x]=low[x]=++num;
sta[++top]=x;
ins[x]=1;
for(int i=head[x];i;i=e[i].nxt)
{
if(!dfn[e[i].to])
{
tarjan(e[i].to);
low[x]=min(low[x],low[e[i].to]);
}
else if(ins[e[i].to])
low[x]=min(low[x],dfn[e[i].to]);
}
if(dfn[x]==low[x])
{
tot++;
int y;
do
{
y=sta[top--];
ins[y]=0;
c[y]=tot;
size[tot]++;//记录环的大小
}while(x!=y);
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
add(x,y);
}
for(int i=1;i<=n;i++)
if(!dfn[i])tarjan(i);
for(int x=1;x<=n;x++)
for(int i=head[x];i;i=e[i].nxt)
if(c[x]!=c[e[i].to])
{
add_w(c[x],c[e[i].to]);//建新图
d[c[e[i].to]]++;
}
for(int i=1;i<=tot;i++)
if(!d[i])
q.push(make_pair(i,1));
while(q.size())//拓扑排序
{
pair<int,int> flag=q.front();
q.pop();
ans=max(ans,flag.second);
if(!--size[flag.first])//跑出了环
{
for(int i=headw[flag.first];i;i=wzc[i].nxt)
{
d[wzc[i].to]--;
if(!d[wzc[i].to])
q.push(make_pair(wzc[i].to,flag.second+1));
}
}
else q.push(make_pair(flag.first,flag.second+1));//注意环的大小
}
cout<<ans<<endl;
return 0;
}
rp++
[CSP-S模拟测试]:轰炸行动(bomb)(塔尖+拓扑排序+语文)的更多相关文章
- [CSP-S模拟测试]:Permutation(线段树+拓扑排序+贪心)
题目描述 你有一个长度为$n$的排列$P$与一个正整数$K$你可以进行如下操作若干次使得排列的字典序尽量小对于两个满足$|i−j|\geqslant K$且$|P_i−P_j|=1$的下标$i$与$j ...
- 2019.8.9 NOIP模拟测试15 反思总结
日常爆炸,考得一次比一次差XD 可能还是被身体拖慢了学习的进度吧,虽然按理来说没有影响.大家听的我也听过,大家学的我也没有缺勤多少次. 那么果然还是能力问题吗……? 虽然不愿意承认,但显然就是这样.对 ...
- Android单元测试与模拟测试详解
测试与基本规范 为什么需要测试? 为了稳定性,能够明确的了解是否正确的完成开发. 更加易于维护,能够在修改代码后保证功能不被破坏. 集成一些工具,规范开发规范,使得代码更加稳定( 如通过 phabri ...
- [开源]微信在线信息模拟测试工具(基于Senparc.Weixin.MP开发)
目前为止似乎还没有看到过Web版的普通消息测试工具(除了官方针对高级接口的),现有的一些桌面版的几个测试工具也都是使用XML直接请求,非常不友好,我们来尝试做一个“面向对象”操作的测试工具. 测试工具 ...
- 安装nginx python uwsgi环境 以及模拟测试
uwsgi帮助文档: http://uwsgi-docs-cn.readthedocs.io/zh_CN/latest/WSGIquickstart.html http://uwsgi-docs.re ...
- 利用Python中的mock库对Python代码进行模拟测试
这篇文章主要介绍了利用Python中的mock库对Python代码进行模拟测试,mock库自从Python3.3依赖成为了Python的内置库,本文也等于介绍了该库的用法,需要的朋友可以参考下 ...
- 转 C#实现PID控制的模拟测试和曲线绘图
C#实现PID控制的模拟测试和曲线绘图 本文分两部分,一部分是讲PID算法的实现,另一部分是讲如何用动态的曲线绘制出PID运算的结果. 首先,PID算法的理论模型请参考自动控制理论,最早出现的是模 ...
- Mockito:一个强大的用于Java开发的模拟测试框架
https://blog.csdn.net/zhoudaxia/article/details/33056093 介绍 本文将介绍模拟测试框架Mockito的一些基础概念, 介绍该框架的优点,讲解应用 ...
- NOIP模拟测试1(2017081501)
好,今天是cgg第一次举行模拟测试,希望各位支持. 时间限制:2小时 题目链接: 题目一:水得都没名字了 题目二:车站 题目三:选数 不要觉得2小时太少,我的题目很良心,都很简单. 答案可以在模拟测试 ...
随机推荐
- Appium-入门实例1
参考:(https://blog.csdn.net/zh175578809/article/details/76862590) 第一步:启动虚拟设备 在运行App之前,首先需要创建一个Android模 ...
- sqluldr2 oracle直接导出数据为文本的小工具使用
近期客户有需求,导出某些审计数据,供审计人进行核查,只能导出成文本或excel格式的进行查看,这里我们使用sqluldr2工具进行相关数据的导出. oracle导出数据为文本格式比较麻烦,sqluld ...
- 安全运维 - Linux系统攻击回溯
入侵排查思路 (1)- 日志分析 日志分析 默认日志路径: /var/log 查看日志配置情况: more /etc/rsyslog.conf 重要日志: 登录失败记录: /var/log/btmp ...
- vue组件通信之父子组件通信
准备工作: 首先,新建一个项目,如果这里有不会的同学,可以参考我转载过的文章 http://www.cnblogs.com/Sky-Ice/p/8875958.html vue 脚手架安装及新建项目 ...
- 20191103 《Spring5高级编程》笔记-第3章
第3章 在Spring中引入IoC和DI 依赖注入是IOC的一种特殊形式,尽管这两个术语经常可以互换使用. 3.1 控制反转和依赖注入 IOC的核心是DI,旨在提供一种更简单的机制来设置组件依赖项,并 ...
- [Python3 练习] 008 欧几里德算法
题目:写个"欧几里德算法"的小程序 (1) 描述 我知识浅薄,一开始被"欧几里德"的大名唬住了,去搜了一下才知道这就是高中时学过的"辗转相除法&quo ...
- Mybatis-学习笔记(1)SqlSessionFactory、SqlSession、Mybatis配置文件configuration的属性标签
1.mybatis引入项目,只需要引入mybatis-x.x.x.jar包即可. (当然数据库驱动的引入必不可少) 2.SqlSessionFactory 由SqlSessionFactoryBuil ...
- Java设计模式——模板方法设计模式(abstract修饰)
解释: 一个抽象类中,有一个主方法,再定义 1...n 个方法,可以是抽象的,也可以是实际的方法,定义一个类,继承该抽象类,重写抽象方法,通过调用抽象类,实现对子类的调用. 解决的问题: 当功能内部一 ...
- Java学习day7面向对象编程1-对象和类
一.Java编程中对象和类的概念 1,什么是类? 答:类是客观存在的,抽象的,概念的东西. 2,什么是对象? 答:对象是具体的,实际的,代表一个事物.例如:车是一个类,汽车,自行车就是他的对象. 关于 ...
- 牛客练习赛51 C 勾股定理https://ac.nowcoder.com/acm/contest/1083/C
题目描述 给出直角三角形其中一条边的长度n,你的任务是构造剩下的两条边,使这三条边能构成一个直角三角形. 输入描述: 一个整数n. 输出描述: 另外两条边b,c.答案不唯一,只要输出任意一组即为合理, ...