轰炸(bomb)
【题目描述】
有n座城市,城市之间建立了m条有向的地下通道。
你需要发起若干轮轰炸,每轮可以轰炸任意多个城市。但每次轰炸的城市中,不能存在两个不同的城市i,j满足可以通过地道从城市i到达城市j。
你需要求出最少需要多少轮可以对每座城市都进行至少一次轰炸。
【输入数据】
第一行两个整数n,m。接下来m行每行两个整数a,b表示一条从a连向b的单向边。
【输出数据】
一行一个整数表示答案。
【样例输入】
5 4
1 2
2 3
3 1
4 5
【样例输出】
3
【数据范围】
对于20%的数据,n,m<=10。
对于40%的数据,n,m<=1000。
对于另外30%的数据,保证无环。
对于100%的数据,n,m<=1000000。

首先,如果图中无环的话,答案就是图中最长链的点数。

我们从两个方面来证明这个答案的正确性:

1. 因为最长链上一次最多轰炸一个点,所以答案肯定>=最长链的长度。

2.设f[i]为从i开始的最长链长度,那么我们就在第i轮轰炸所有f[x]==i的x城市。因为同一条链上的f值肯定都不相同,所以这样肯定合法。所以答案<=最长链长度。

然后就证明了答案就是最长链的点数。

那么有环的话怎么办??

因为一个强联通分量中的点都是可以互达的,所以我们可以缩点之后把点权设置为这个点中原图的点的数量,然后这个图的最长链(路径上点权和最大的路径)就是答案。

#include<bits/stdc++.h>
#define ll long long
#define maxn 1000005
#define pb push_back
using namespace std;
int s[maxn],tp=0;
int lt[maxn],f[maxn];
int to[maxn],ne[maxn];
int hd[maxn],num=0,n,m;
int siz[maxn],k=0,dc=0;
int dfn[maxn],low[maxn];
vector<int> g[maxn]; inline int read(){
int x=0; char ch=getchar();
for(;!isdigit(ch);ch=getchar());
for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';
return x;
} void dfs(int x){
dfn[x]=low[x]=++dc;
s[++tp]=x; for(int i=hd[x];i;i=ne[i])
if(!dfn[to[i]]){
dfs(to[i]);
low[x]=min(low[x],low[to[i]]);
}
else if(!lt[to[i]]) low[x]=min(low[x],dfn[to[i]]); if(low[x]==dfn[x]){
k++;
for(;;){
lt[s[tp]]=k,siz[k]++;
if(s[tp--]==x) break;
}
}
} inline void tarjan(){
for(int i=1;i<=n;i++) if(!dfn[i]) dfs(i); int S,T;
for(int i=1;i<=n;i++){
S=lt[i];
for(int j=hd[i];j;j=ne[j]){
T=lt[to[j]];
if(S!=T) g[S].pb(T);
}
}
} int dp(int x){
if(f[x]) return f[x]; int to;
for(int i=g[x].size()-1;i>=0;i--){
to=g[x][i];
f[x]=max(f[x],dp(to));
}
f[x]+=siz[x]; return f[x];
} int main(){
freopen("bomb.in","r",stdin);
freopen("bomb.out","w",stdout); int uu,vv;
n=read(),m=read();
for(int i=1;i<=m;i++){
uu=read(),vv=read();
to[i]=vv,ne[i]=hd[uu],hd[uu]=i;
} tarjan();
int ans=0;
for(int i=1;i<=k;i++) ans=max(ans,dp(i));
printf("%d\n",ans); return 0;
}

  

某考试 T2 bomb的更多相关文章

  1. 9.13 考试 T2 区间

    删区间 题意: 给出一个长度为

  2. 某考试T2 frog

    题目背景 无 题目描述 数轴上有 n 只青蛙,分别编号为 1 到 n.青蛙 i 的初始位置的坐标为 xi. 它们准备进行如下形式的移动:每轮包括 m 次跳跃,第 i 次跳跃由青蛙 ai(1 < ...

  3. 某考试 T2 Tree

    2 树 2.1 题目描述 给一棵n 个节点的树,节点分别编号为0 到n - 1.你可以通过如下的操作来修改这棵树:首先先删去树上的一条边,此时树会分裂为两个连通块,然后在两个连通块之间加上一条新的边使 ...

  4. 某考试 T2 yja

    2.1 Description 在平面上找 n 个点, 要求这 n 个点离原点的距离分别为 r1, r2, ..., rn. 最大化这 n 个点构成的凸包面积, 凸包上的点的顺序任意. 2.2 Inp ...

  5. 题解 2020.10.24 考试 T2 选数

    题目传送门 题目大意 见题面. 思路 本来以为zcx.pxj变强了,后来发现是SPJ出问题了...考试的时候感觉有点人均啊...结果自己还是只想出来一半. 我们假设 \(f(x)=(\lfloor\f ...

  6. 2019.3.7考试T2 离线数论??

    $ \color{#0066ff}{ 题目描述 }$ 一天,olinr 在 luogu.org 刷题,一点提交,等了一分钟之后,又蛙又替. olinr 发动了他的绝招,说:"为啥啊???&q ...

  7. 某考试 T2 orzcyr

    非常nice的一道行列式的题目. 考虑如果没有路径不相交这个限制的话,那么这个题就是一个行列式:设 a[i][j] 为从编号第i小的源点到编号第j小的汇点的路径条数,那么矩阵a[][]的行列式就是的答 ...

  8. 2019.2.26考试T2 矩阵快速幂加速DP

    \(\color{#0066ff}{题解 }\) 可以发现, 数据范围中的n特别小,容易想到状压 可以想到类似于状压DP的思路,按列进行转移 那么应该有3维,\(f[i][j][k]\)代表到第i列, ...

  9. 2019.2.10考试T2, 多项式求exp+生成函数

    \(\color{#0066ff}{ 题目描述 }\) 为了减小文件大小,这里不写一堆题目背景了. 请写一个程序,输入一个数字N,输出N个点的森林的数量.点有标号. 森林是一种无向图,要求图中不能存在 ...

随机推荐

  1. Makefile基础(三)

    第一章:C语言之Makefile基础(一) 第二章:C语言之Makefile基础(二) 再来看一个简单的例子: [root@localhost linux_c]# cat Makefile foo = ...

  2. LayoutInflater的用法

    Instantiates a layout XML file into its corresponding View objects. It is never used directly. Inste ...

  3. nginx的常用负载均衡算法,分别是

    随机分配,hash一致性分配,最小连接数分配,主备分配 随机,轮训,一致性哈希,主备,https://blog.csdn.net/liu88010988/article/details/5154741 ...

  4. ASP.Net教程系列:多线程编程实战(一)

    Web开发中使用多线程可以增强用户体验,尤其是多用户.多任务.海量数据和资源紧张的情况下.所以我们的ASP.Net教程设立多线程编程实战专题.下面这些代码范例都是入门级的,希望对对大家学习ASP.Ne ...

  5. 使用css Flexbox实现垂直居中

    CSS布局对我们来说一直是个噩梦,我们都认为flexbox是我们的救世主.是否真的如我们说说,还有待观察,但是flexbox确非常轻松的解决css长久一来比较难解决的居中问题.让我们来看看到底有多容易 ...

  6. [python][oldboy]字符串 format

    #coding=utf8 def format(self, *args, **kwargs): # known special case of str.format """ ...

  7. 【bzoj2729】[HNOI2012]排队 组合数学+高精度

    题目描述 某中学有 n 名男同学,m 名女同学和两名老师要排队参加体检.他们排成一条直线,并且任意两名女同学不能相邻,两名老师也不能相邻,那么一共有多少种排法呢?(注意:任意两个人都是不同的) 输入 ...

  8. JavaScript阻止冒泡和取消事件默认行为

    //功能:停止事件冒泡 function stopBubble(e) { if ( e && e.stopPropagation ) { e.stopPropagation(); } ...

  9. 刷题总结——字符串(ssoj)

    题目: 给定n个小的字符串T和一个大的字符串S,先输出T总共再S中出现了多少次 然后q个询问···每次修改S上的一个字母,然后再次输出上述答案··· n小于1000,q<200000,T的总长度 ...

  10. 算法复习——树形dp

    树形dp的状态转移分为两种,一种为从子节点到父节点,一种为父节点到子节点,下面主要讨论子节点到父亲节点的情况: 例题1(战略游戏): 这是一道典型的由子节点状态转移到父节点的问题,而且兄弟节点之间没有 ...