描述 Description
在社会经济高速发展的今天,借助高科技手段,组建太空战队的愿望就快实现了。
战队属下有N个航天员。作为空军选拔上来的佼佼者,每个航天员都有与生俱来的骄傲——他们每个人都认为自己是最强的或者是第二强的。这样,如何分组就成了司令官的难题了。司令官分组的方法是这样的:
步骤1:任意选择一个未被分组的航天员,记为当前航天员.
步骤2:把当前航天员分入一个新的组.
步骤3:如果当前航天员心目中最强的那个航天员(记为Q航天员)还没有被分组,那么把Q航天员分入当前航天员所在组,并把Q航天员作为当前航天员并重复步骤3;如果Q航天员已经被分组,那么重复步骤1,直至所有航天员都被分入了某个组。
司令官想请你帮忙计算:按上面的分组方式,最多/最少能分成几个组。
输入格式 Input Format
第一行一个整数N,表示航天员的数目。
接下来N行每行1个整数,第i+1行的整数a[i](1<=a[i]<=N)表示第i位航天员心目中最强的航天员。如果a[i]=i,则表示第i个航天员认为自己是最强的。
输出格式 Output Format
一行,用空格隔开的两个整数A,B,表示按照司令官的分组方法最多和最少能够分成多少组.
样例输入 Sample Input [ 复制数据]
4 2 3 4 2
样例输出 Sample Output [ 复制数据]
2 1
时间限制 Time Limitation
每个测试点1s
注释 Hint
组数最多的一种分组过程:
首先把2分入第一组,接下来,按照第3步的要求,3、4应该也被分入第一组。
接下来,把1分入第2组。

组数最少的一种分组过程:
首先把1分入第一组,接下来,按照第3步的要求,2、3、4也应该被分入第一组。

对于50%的数据,N<=1000.
对于100%的数据,N<=100000.

这道题看似简单,实则不然。

很容易看出来的是,最多的个数就是强连通分量的个数。即每次选择一个没有出度的强连通分量然后把它去除,必然是最大解。

证明:

假设强连通分量A无出度,强连通分量B又出度,并有一条边到A。
如果先选择A中的一个点,则B必定被访问,因此组数不会因为B而减少。

分两种情况:当A有入度,则组数不会因为B而减少。

当A无入度,则A和B被分入同一组,组数减1。

综上所述,每次选择有入度的强连通分量,答案总是小于等于每次选择没有入度的强连通分量所得的答案。

因此最大解等于强连通分量个数。

根据以上我们容易发现每次选择无入度的强连通分量,恰好是最小解!

实现方式就是缩点建图。

注意求最小解,我一开始没有严格证明,想当然地数连通分量的个数,忽略了这是有向图的问题。存在这样的反例:

如果是错误的方法,算出来是1。而正确的方法算出来应该是2。很明显左边两个点不能够分到同一组。

#include <cstdio>
#include <string>
#include <cstring>long T = 0;
long DFN[100010];
long LOW[100010];
bool Instack[100010];
long Belong[100010];
long Stack[100010];
bool vis[100010];
long cnt = 0;
bool rudu[100010];
long e[100010];
long top = 0;long getint()
{long rs=0;bool sgn=1;char tmp;do tmp=getchar();while (!isdigit(tmp)&&tmp-'-');if (tmp=='-'){tmp=getchar();sgn=0;}do rs=(rs<<3)+(rs<<1)+tmp-'0';while (isdigit(tmp=getchar()));return sgn?rs:-rs;
}void tarjan(long u)
{DFN[u] = LOW[u] = ++T;Instack[u] = true;Stack[++top] = u;if (!DFN[e[u]]){tarjan(e[u]);if (LOW[e[u]] < LOW[u]){LOW[u] = LOW[e[u]];}}else if (Instack[e[u]]){if (DFN[e[u]] < LOW[u]){LOW[u] = DFN[e[u]];}}if (LOW[u] == DFN[u]){long v;cnt ++;do{v = Stack[top--];Belong[v] = cnt;Instack[v] = false;}while (v != u);}
}int main()
{freopen("universe.in","r",stdin);freopen("universe.out","w",stdout);long n = getint();for (long i=1;i<n+1;i++){e[i] = getint();}for (long i=1;i<n+1;i++){if (!DFN[i]){tarjan(i);}}printf("%ld",cnt);for (long i=1;i<n+1;i++){long f = Belong[i];long t = Belong[e[i]];if (f != t){rudu[t] = true;}}long ans2 = 0;for (long i=1;i<cnt+1;i++){if (!rudu[i]){ans2 ++;}}printf(" %ld",ans2);return 0;
}

【强连通分量】太空战队相关推荐

  1. 极小连通子图和极大连通子图_强连通分量与拓扑排序

    前言 由于GacUI里面开始多处用上拓扑排序,我决定把之前瞎JB搞出来的算法换掉,换成个正式的.之前我自己弄了个写起来很简单的算法,然后每一处需要用到的地方我就重新做一遍.当然这样肯定也是不行的,我觉 ...

  2. Tarjan算法应用 (割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)问题)...

    转载自:http://hi.baidu.com/lydrainbowcat/blog/item/2194090a96bbed2db1351de8.html 基本概念: 1.割点:若删掉某点后,原连通图 ...

  3. HDU4635(强连通分量+Kosaraju算法)

    题意:给出一个有向图,最多添加多少条边使这个图依然不是强连通图:当这个图是强连通图时,输出-1: 求解思路:强连通分量求解: 强连通图:在有向图中,任意节点除法都可以到达其余所有节点,则称为强连通图. ...

  4. poj3352(强连通分量)

    题意:添加多少边才能使这个无向图为双连通分量. 注意:双连通分量适用于无向图:而强连通分量适用于有向图.但是这两个概念都是一样的. #include<iostream> #include& ...

  5. poj2553(强连通分量)

    题意:给出有向图,图的底部是所有汇节点的子集,即,底部(G)={v∈V\x-∀w∈V:(v→w)⇒(w→v)},w在--里面G可以从v, v也可从w.让我们求有多少个点是绘点的问题. 思路:先求解出强 ...

  6. poj2186(强连通分量)

    思路:找出出度为0 的顶点,如果出度为0的顶点大于1,则解为零,否则解就是出度为零的顶点的连通分支数. 刚开始是没有理解这道题的,也是看了大神之后才理解的. 方法一: #include<iost ...

  7. poj1236(强连通分量)

    题意: (1).至少需要向多少个学校发放软件,要使这个网络中的所有学校都能得到软件 (2).至少需要添加多少条边,才能使这个网络成为一个强连通分量图. 思路:首先求解强连通分量,如果不是同一个强连通分 ...

  8. HDU5934(强连通分量)

    题意:主要在诈弹爆炸的范围内如果存在其他的诈弹,那么在周围的诈弹也将会被引爆,这样思路就可以想到强连通分量了: 思路:先求解强连通分量,在找到强连通分量时,也求解出这个强连通分量的最小费用mincos ...

  9. HDU2767(强连通分量+Kosaraju算法)

    题意:需要加多少边才能把一个图变成强连通分量 强连通图:在有向图中,任意节点除法都可以到达其余所有节点,则称为强连通图. 强连通分量:在非强连通图的有向图中,选取部分点为强连通图,该强连通子图称为强连 ...

最新文章

  1. 如何制作自己的CocoaPod库
  2. Torchvision目标检测模型训练过程记录
  3. [YTU]_2878( 结构体--学生信息排序)
  4. Activity生命周期(二)
  5. 瑞士加密银行SEBA将发行B轮融资股票作为证券代币
  6. mysql中的事务_mysql中的事务,你理解嘛?
  7. 【面试题系列|前端面试题】前端高频面试题总结(2021年最新版)
  8. 【状压DP】易懂讲解状态压缩/状态压缩DP
  9. 回忆我的过去一年2020年考研以及研究生规划
  10. 七、VUE基础——悦听音乐播放器案例(vue+axios)
  11. jquery 源码分析系列1
  12. Python selenium定位动态下拉框
  13. java计算某一天是这一年的第几天
  14. android自动划屏实现,OSC首发:android中的左右滑屏实现By ViewPager
  15. 【青龙面板】快手JS版脚本
  16. Android界面开发基础
  17. web开发权威,一个合格的初级前端工程师需要掌握的模块笔记
  18. dbus系列教程(2)理解dbus核心概念
  19. Python后台开发基础——Web前端基础
  20. eBay信用评价体系全解析

热门文章

  1. windows10家庭版如何修改Administrators名字
  2. day02 Python:列表
  3. 【蓝桥杯】受伤的皇后
  4. 鼓励参与计算机考试宣传标语,考试宣传标语
  5. c语言printf结构体,小白来学C语言之结构体
  6. python自测100题,都掌握你离月薪过万不远了
  7. QXlsx读写Excel表格
  8. 网络游戏的服务器在哪个文件夹,手里有一份网络游戏的服务端(预言OL) 现在缺少GM命令,在服务端里也找不到command这个文件...
  9. 连续型随机变量的函数分布及例题
  10. layui之laydate日期组件在done中重新渲染