小C图
2017-08-19 17:51
113 查看
题目描述
C 非常喜欢图论,他想出了一张 N 个点 M 条边的有向图,其中点记为 1…N,边记为 1…M。C 觉得一张没有环的并且边的编号连续的图是完美的,他称之为小 C 图,现在,他希望你能在这张有向图上,找出最少的小 C 图使得这些小 C 图能够包含所有边。为了检验你确实找出了所有的小 C 图,你需要把每张小 C 图包含的边的编号区间输出。
输入格式
输入的第一行有两个整数 N,M。接下来 M 行,每行两个整数 X,Y,第 i 行代表编号为 i 的边可以从 X 通向 Y。
输出格式:
输出的第一行一个整数 answer 代表能找出的小 C 图的最少数量。接下来 answer 行,每行两个正整数,按照升序输出第 i 张小 C 图包含的边的区间。
若有多组解则输出第 1 张小 C 图右端点最大的解,若仍有多组解则输出第 2 张小 C 图右端点最大的解,依次类推。
样例输入:
5 41 2
2 3
3 4
4 5
样例输出:
11 4
数据范围: 对于 30%的数据,n<=1000,m<= 7000,
对于 60%的数据,保证数据随机,
对于 100%的数据,n<=100000,m<=300000,保证无自环.
【题目讲解】
我一开始做这道题,反正是理解错题意了的,导致一直都没想出来。。。
这道题题意大概就是说,它给你一系列的边,要你建一种图,这种图可以分为很多个(并且这种图的每条边可以不连续,也就是说不一定要相连),每个图的边的编号(每条边输进来的顺序)要是连续的,并且该图不能存在环!然后题目要求输出小C图的总个数,并且把每个小C图的边包含的区间输出来。
显然这题是贪心,因为每条边都要覆盖到,我们可以找到从第一个点开始的最长区间,然后从区间右端点开始重新找。
基于这个思想,我们就可以暴力做了,枚举边,用拓扑或者 tarjan 判环。
时间复杂度:O(nm),空间复杂度:O(m),期望得分:30 分。
然而实际上我们并不需要枚举每条边,二分一下答案,暴力判环就好了,然而实际上是会被卡掉的,由于数据随机,这种方法是可以过的。
时间复杂度:O(mnlogm),空间复杂度:O(m),期望得分:60 分。
发现二分的局限性在于每条边被扫过不止一次,考虑一种更优的方法使得每条边只被扫过一次,考虑先倍增找出最长区间长度所在的区间,再二分+判环。
(这里二分加判环,是因为我们在做倍增的时候,会有两个小的区间,得到一个大区间,但有可能是前一个小区间满足条件,而后一个小区间不满足条件,但第二个区间有部分加到前一个小区间中也会满足条件,于是这里要二分并且要判环,当时我是没懂)
时间复杂度:O(mlogm+nlogm),空间复杂度:O(m),期望得分:100 分。
以上是出题人给的解析(本蘜加了点修改)
源代码
相关文章推荐
- C++二分查找在搜索引擎多文档求交的应用分析
- C语言数据结构中二分查找递归非递归实现并分析
- C++ 中二分查找递归非递归实现并分析
- C语言编程中实现二分查找的简单入门实例
- C#二分查找算法实例分析
- JavaScript实现二分查找实例代码
- 浅谈选择、冒泡排序,二分查找法以及一些for循环的灵活运用
- 二分查找算法在C/C++程序中的应用示例
- C++二分查找(折半查找)算法实例详解
- PHP二分查找算法示例【递归与非递归方法】
- php实现的二分查找算法示例
- js基本算法:冒泡排序,二分查找的简单实例
- 在MySQL中实现二分查找的详细教程
- 详解图的应用(最小生成树、拓扑排序、关键路径、最短路径)
- C++二分查找算法实例
- java 算法二分查找和折半查找
- Java实现二分查找算法实例分析
- JAVA冒泡排序和二分查找的实现
- Python实现二分查找与bisect模块详解
- Python基于二分查找实现求整数平方根的方法