题目描述

战狂也在玩《魔方王国》。他只会征兵而不会建城市,因此他决定对小奇的城市进行轰炸。
小奇有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. charles_01_打断点修改接口请求&返回数据

    前言 测试过程中,为了模拟某场景测试,经常需要修改接口请求或者返回数据.可通过抓包工具打断点,实现模拟测试场景.常用的抓包工具charles和fiddler均可打断点mock数据.由于小编安装了cha ...

  2. react 样式的写法之一 ---》styled-components的基本使用

    [react]---styled-components的基本使用---[WangQi]   一.官网地址 https://www.styled-components.com/ 二.styled-com ...

  3. oracle--表分区、分区索引

    --|/ range分区 create table sale( product_id varchar2(5), sale_count number(10,2) ) partition by range ...

  4. ODBC Driver Development

    ODBC Driver Development By Vikash Agarwal, May 01, 2002 Open your database system to the world. Vika ...

  5. python pickle模块的用法

    pickle用于python特有的类型,和python的数据类型间进行转换,提供四个功能 dumps,dump,loads,load. pickle 的用法 #pickle.dumps 将数据通过特殊 ...

  6. jmeter 线程数—请求数详解

    一个性能测试请求负载是基于一个线程组完成的.一个测试计划必须有一个线程组.测试计划添加线程组非常简单.在测试计划右键弹出下拉菜单(添加-->Threads(Users)--->线程组)中选 ...

  7. ssh1

    #coding=utf-8 import paramiko ssh = paramiko.SSHClient() #允许链接不在linux上.ssh文件中不在known_hosts文件中的主机 ssh ...

  8. 攻防世界--re1-100

    测试文件:https://adworld.xctf.org.cn/media/task/attachments/dc14f9a05f2846249336a84aecaf18a2.zip 1.准备 获取 ...

  9. vue报错TypeError: Cannot read property 'protocol' of undefined

    错误信息如下所示: isURLSameOrigin.js?3934:57 Uncaught (in promise) TypeError: Cannot read property 'protocol ...

  10. Linux系统性能测试工具(一)——内存带宽测试工具mbw

    本文介绍关于Linux系统(适用于centos/ubuntu等)的内存带宽测试工具-mbw.内存性能测试工具包括: 内存带宽测试工具——mbw: 内存压力测试工具——memtester: 内存综合性能 ...