<题目链接>

题目大意:

有n座城市,城市之间建立了m条有向的地下通道。你需要发起若干轮轰炸,每轮可以轰炸任意多个城市。但每次轰炸的城市中,不能存在两个不同的城市i,j满足可以通过地道从城市i到达城市j。你需要求出最少需要多少轮可以对每座城市都进行至少一次轰炸。
解题分析:
因为每轮轰炸都不能同时炸能够从一点到达另一点的两地,就是说强连通缩点之后在同一条路径上的所有点都不能在同一轮被炸。显然就是让我们求DAG最长路上点的数量,因为这个最长路上的点都只能在不同的轮次被炸,而其它每一条完整路径上的总点数一定小于等于这条最长路径的总点数,所以他们一定能够安排在不同的轮次爆炸。
#include <bits/stdc++.h>
using namespace std; template<typename T>
inline void read(T&x){
x=;int f=;char c=getchar();
while(c<'' || c>''){ if(c=='-')f=-;c=getchar(); }
while(c>='' && c<=''){ x=x*+c-'';c=getchar(); }
x*=f;
}
#define REP(i,s,t) for(int i=s;i<=t;i++)
#define clr(a,b) memset(a,b,sizeof(a))
const int N = 1e6+;
int n,m,cnt1,cnt2,tot,top,scc;
int head1[N],head2[N],dfn[N],low[N],bel[N],num[N],dp[N],instk[N],stk[N]; struct Edge{ int from,to,nxt; }e1[N],e2[N]; inline void add1(int u,int v){
e1[++cnt1]=(Edge){ u,v,head1[u] };head1[u]=cnt1;
}
inline void add2(int u,int v){
e2[++cnt2]=(Edge){ u,v,head2[u] };head2[u]=cnt2;
}
void Tarjan(int u){
dfn[u]=low[u]=++tot;
instk[u]=;stk[++top]=u;
for(int i=head1[u];i;i=e1[i].nxt){
int v=e1[i].to;
if(!dfn[v]){
Tarjan(v);
low[u]=min(low[u],low[v]);
}else if(instk[v])low[u]=min(low[u],dfn[v]);
}
if(dfn[u]==low[u]){
++scc;
while(true){
int v=stk[top--];
instk[v]=;
bel[v]=scc;
num[scc]++; //统计每个强连通分量中的点数
if(v==u)break;
}
}
}
inline void gao(){ //缩点之后正向建图
// for(auto e:e1){
for(int i=;i<=cnt1;i++){
Edge e=e1[i];
int u=e.from,v=e.to;
if(bel[u]!=bel[v])add2(bel[u],bel[v]);
}
}
int DFS(int u){ //记忆化搜索求解DAG最长路
if(dp[u])return dp[u];
int ans=num[u];
for(int i=head2[u];i;i=e2[i].nxt){
int v=e2[i].to;
ans=max(ans,DFS(v)+num[u]);
}
return dp[u]=ans;
}
int main(){
read(n);read(m);
REP(i,,m){
int u,v;read(u);read(v);
add1(u,v);
}
REP(i,,n) if(!dfn[i]) Tarjan(i);
gao();
int ans=-;
for(int i=;i<=scc;i++){
ans=max(ans,DFS(i));
}
printf("%d\n",ans);
}

BZOJ 5450 轰炸 (强连通缩点+DAG最长路)的更多相关文章

  1. UVA11324 The Largest Clique (强连通缩点+DP最长路)

    <题目链接> 题目大意: 给你一张有向图 G,求一个结点数最大的结点集,使得该结点集中的任意两个结点 u 和 v 满足:要么 u 可以达 v,要么 v 可以达 u(u,v相互可达也行). ...

  2. ZOJ 3795 Grouping (强连通缩点+DP最长路)

    <题目链接> 题目大意: n个人,m条关系,每条关系a >= b,说明a,b之间是可比较的,如果还有b >= c,则说明b,c之间,a,c之间都是可以比较的.问至少需要多少个集 ...

  3. BZOJ1093 [ZJOI2007]最大半连通子图 【tarjan缩点 + DAG最长路计数】

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

  4. 「BZOJ1924」「SDOI2010」 所驼门王的宝藏 tarjan + dp(DAG 最长路)

    「BZOJ1924」[SDOI2010] 所驼门王的宝藏 tarjan + dp(DAG 最长路) -------------------------------------------------- ...

  5. 【bzoj1179】[Apio2009]Atm Tarjan缩点+Spfa最长路

    题目描述 输入 第一行包含两个整数N.M.N表示路口的个数,M表示道路条数.接下来M行,每行两个整数,这两个整数都在1到N之间,第i+1行的两个整数表示第i条道路的起点和终点的路口编号.接下来N行,每 ...

  6. NYOJ16 矩形嵌套(DAG最长路)

    矩形嵌套 紫书P262 这是有向无环图DAG(Directed Acyclic Graph)上的动态规划,是DAG最长路问题 [题目链接]NYOJ16-矩形嵌套 [题目类型]DAG上的dp & ...

  7. uva 10051 Tower of Cubes(DAG最长路)

    题目连接:10051 - Tower of Cubes 题目大意:有n个正方体,从序号1~n, 对应的每个立方体的6个面分别有它的颜色(用数字给出),现在想要将立方体堆成塔,并且上面的立方体的序号要小 ...

  8. Tarjan缩点+Spfa最长路【p3627】[APIO2009] 抢掠计划

    Description Siruseri 城中的道路都是单向的.不同的道路由路口连接.按照法律的规定, 在每个路口都设立了一个 Siruseri 银行的 ATM 取款机.令人奇怪的是,Siruseri ...

  9. 简单Dp----最长公共子序列,DAG最长路,简单区间DP等

    /* uva 111 * 题意: * 顺序有变化的最长公共子序列: * 模板: */ #include<iostream> #include<cstdio> #include& ...

随机推荐

  1. 【改】linux中分区的概念

    1.目录和分区 区别:Linux的分区是物理上的概念,从物理上将存储空间分开:Linux的目录是逻辑上的概念,Linux的目录树实际上是一个分区之间的数据逻辑结构关系,不是物理结构: 联系:一个分区必 ...

  2. python常用函数 Y

    yield有点像return,但他会在下一次执行的时候从上次结束点继续执行,带有 yield 的函数在 Python 中被称之为 generator(生成器),生成器无法通过索引获取数据,同时也承诺使 ...

  3. windowserver 常用命令

    1.查看端口占用: netstat -ano | findstr "服务端口号"2.查看程序运行id: tasklist | findstr  nginx 3.杀死进程  tskk ...

  4. BZOJ 1911 特别行动队 (斜率优化)

    $ BZOJ~1911~*~ $ 特别行动队: (斜率优化) $ solution: $ 感觉这道题目还是比较常规的,首先我们很容易想到DP,因为题目里面说了选出的人都是连续的,这意味着我们可以从前往 ...

  5. django 修改字段后,同步数据库,失败:django.db.utils.InternalError: (1054, "Unknown column 'api_config.project_id_id' in 'field list'")

    问题原因是,修改字段后,同步失败了,然后执行查询的时候,就会提示这个错误,这个字段没有 最暴力的方法可以直接在数据库中修改字段,但是修改后,models没同步,可能会存在问题,因此开始我的百度之旅(这 ...

  6. LightOJ 1079 Just another Robbery (01背包)

    题目链接 题意:Harry Potter要去抢银行(wtf???),有n个银行,对于每个银行,抢的话,能抢到Mi单位的钱,并有pi的概率被抓到.在各个银行被抓到是独立事件.总的被抓到的概率不能超过P. ...

  7. CentOS下安装Chrome浏览器

    1. 下载安装脚本, 在下载目录中,执行以下命令,将安装脚本下载到本地 wget https://intoli.com/install-google-chrome.sh 2.然后授予可执行权限 chm ...

  8. 新手立体四子棋AI教程(4)——启发式搜索与主程序

    通过前面几篇文章的学习,我们的四子棋程序已经有了框架.搜索几大部分,但是还有着不少问题,我们的程序只能迭代很有限的步骤,导致棋力低下,在这一篇我们将通过启发式搜索极大的优化搜索效率. 一.原因 我们之 ...

  9. 四-3、Mirror(镜像)、Spin(旋转)、创建组

    1.Mirror 1.针对单个器件 2.针对整个模块 2.Spin(旋转)(平时用的比较少) 3.创建组(经常用到)(主要是在布局时,发现后期需要移动整个模组)(创建为group) 1.创建组---- ...

  10. css 实现div内显示两行或三行,超出部分用省略号显示

    一.div内显示一行,超出部分用省略号显示 white-space: nowrap;    overflow: hidden;    text-overflow: ellipsis; 二.div内显示 ...