题目描述

战狂也在玩《魔方王国》。他只会征兵而不会建城市,因此他决定对小奇的城市进行轰炸。
小奇有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)(塔尖+拓扑排序+语文)的更多相关文章

  1. [CSP-S模拟测试]:Permutation(线段树+拓扑排序+贪心)

    题目描述 你有一个长度为$n$的排列$P$与一个正整数$K$你可以进行如下操作若干次使得排列的字典序尽量小对于两个满足$|i−j|\geqslant K$且$|P_i−P_j|=1$的下标$i$与$j ...

  2. 2019.8.9 NOIP模拟测试15 反思总结

    日常爆炸,考得一次比一次差XD 可能还是被身体拖慢了学习的进度吧,虽然按理来说没有影响.大家听的我也听过,大家学的我也没有缺勤多少次. 那么果然还是能力问题吗……? 虽然不愿意承认,但显然就是这样.对 ...

  3. Android单元测试与模拟测试详解

    测试与基本规范 为什么需要测试? 为了稳定性,能够明确的了解是否正确的完成开发. 更加易于维护,能够在修改代码后保证功能不被破坏. 集成一些工具,规范开发规范,使得代码更加稳定( 如通过 phabri ...

  4. [开源]微信在线信息模拟测试工具(基于Senparc.Weixin.MP开发)

    目前为止似乎还没有看到过Web版的普通消息测试工具(除了官方针对高级接口的),现有的一些桌面版的几个测试工具也都是使用XML直接请求,非常不友好,我们来尝试做一个“面向对象”操作的测试工具. 测试工具 ...

  5. 安装nginx python uwsgi环境 以及模拟测试

    uwsgi帮助文档: http://uwsgi-docs-cn.readthedocs.io/zh_CN/latest/WSGIquickstart.html http://uwsgi-docs.re ...

  6. 利用Python中的mock库对Python代码进行模拟测试

    这篇文章主要介绍了利用Python中的mock库对Python代码进行模拟测试,mock库自从Python3.3依赖成为了Python的内置库,本文也等于介绍了该库的用法,需要的朋友可以参考下     ...

  7. 转 C#实现PID控制的模拟测试和曲线绘图

    C#实现PID控制的模拟测试和曲线绘图   本文分两部分,一部分是讲PID算法的实现,另一部分是讲如何用动态的曲线绘制出PID运算的结果. 首先,PID算法的理论模型请参考自动控制理论,最早出现的是模 ...

  8. Mockito:一个强大的用于Java开发的模拟测试框架

    https://blog.csdn.net/zhoudaxia/article/details/33056093 介绍 本文将介绍模拟测试框架Mockito的一些基础概念, 介绍该框架的优点,讲解应用 ...

  9. NOIP模拟测试1(2017081501)

    好,今天是cgg第一次举行模拟测试,希望各位支持. 时间限制:2小时 题目链接: 题目一:水得都没名字了 题目二:车站 题目三:选数 不要觉得2小时太少,我的题目很良心,都很简单. 答案可以在模拟测试 ...

随机推荐

  1. 什么是HIS、PACS、LIS、RIS

    什么是HIS?医院信息系统的定义(HIS)医院信息系统(Hospital Information System,HIS)在国际学术界已公认为新兴的医学信息学(Medical Informatics)的 ...

  2. oracle--批量删除部分表,将某一列拼接成字符串

    1.查询要批量删除的表 SELECT * FROM USER_TABLES SELECT 'DROP '||'TABLE ' || TABLE_NAME ||' ;' ,1 FROM USER_TAB ...

  3. 实现atoi

    1. 去掉首位空格 2. 判断首位是否有正负号 3. 判断各位是否是0~9,有其他字符直接返回当前结果   public class Solution { public int atoi(String ...

  4. mysql字符串拆分实现split功能

    转自:https://blog.csdn.net/pjymyself/article/details/81668157有分隔符的字符串拆分题目要求数据库中 num字段值为: 实现的效果:需要将一行数据 ...

  5. 【mysql】select子句顺序

    sleect…from (1)where (2)group by (3)having (4)order by (5)limit

  6. Maven-maven插件(1)添加主类信息到MANIFEST.MF

    1.以前面的HelloWorld项目为例,在pom.xml中添加如下代码,指定插件 <build> <plugins> <plugin> <groupId&g ...

  7. [BZOI 3994] [SDOI2015]约数个数和(莫比乌斯反演+数论分块)

    [BZOI 3994] [SDOI2015]约数个数和 题面 设d(x)为x的约数个数,给定N.M,求\(\sum _{i=1}^n \sum_{i=1}^m d(i \times j)\) T组询问 ...

  8. Fiddler用法整理

    目 录 1 Fiddler的基本介绍 1.1 下载安装 1.2 适用平台 2 Fiddler的工作原理 3 同类工具 4 捕获非IE浏览器的会话 5 捕获不同请求的设置方法 5.1 Web HTTPS ...

  9. uWSGI、uwsgi、WSGI、之间的关系,为什么要用nginx加uWSGI部署。

    WSGI 协议 WSGI:是一种协议规范,起到规范参数的作用,就像告诉公路一样,规定超车靠右行,速度不低于90km/h,等.但这一切都是对双方进行沟通,比如,重庆到武汉这条高速路,这儿重庆和武汉就各为 ...

  10. 什么是 Python?

     Python 是一种编程语言,它有对象.模块.线程.异常处理和自动内存管理,可以加入其他语言的对比.  Python 是一种解释型语言,Python 在代码运行之前不需要解释.  Python 是动 ...