本文主要是介绍3971: circle,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
时间限制: 1 Sec 内存限制: 512 MB O2
提交: 122 解决: 23
[提交][状态][博客][加入收藏]
题目描述
小w 的男朋友送给小w 一个nn个点mm条边的图,并且刁难小w 要她找出点数最少的正环。
小w 不会做,于是向你求助。
输入
第一行两个整数n,mn,m。
接下来mm行,每行四个数u,v,a,bu,v,a,b,表示从uu走到vv的代价为aa,从vv走到uu的代价为bb(算作两条不同的边)。注意a,ba,b可能为负。
输出
当图中包含正环时,输出点数最少的正环(简单环)的点数。
否则输出0。
样例输入
3 3
1 2 2 -1
2 3 10 -10
3 1 10 -10
样例输出
2
提示
对于前20%20%的数据,n≤7,m≤10n≤7,m≤10。
对于前60%60%的数据,n≤150,m≤2000n≤150,m≤2000。
对于100%100%的数据,1≤n≤300,0≤m≤n(n−1)2,|a|,|b|≤1041≤n≤300,0≤m≤n(n−1)2,|a|,|b|≤104。
数据保证不存在重边和自环。
来源
2018年10月hnsdfz集训
题解
题目要求的是“在长度为正的条件下点数最少”,而“长度为正”这个条件不好维护,故考虑转化为“点数在一个值之内的最大长度“(为什么不是刚好这个值?请见下文),这样只要找到满足长度为正的最小点数即可。
考虑计算每个点数之内的最大长度,可转化为最长路问题:由于要找的是环,故记F[i][j][k]为i个点之内,从j到k的最长路,对于每一个i,只要有任意f[i][j][j]为正,则可行。从i-1个点数之内向i个点数之内转移,每次跑一遍Floyed,效率为n的四次方。
只要将一个n优化为log即可,而可能优化的只有第一维,那最合适的应该是倍增了。将i改为2的i次方,转移显然。考虑如何统计答案,参照倍增LCA的思想,初始的矩阵为走0步,i从大到小枚举,若走完2的i次方步可行则不走,否则就走,到最后再走一步即可。因为若2的i次方可行,则更大的一定可行,即满足单调性,所以可以这样做(倍增LCA也是由于这样的单调性才可行)。 因此,对于状态F的设计,不应当是恰好i个点(因为不具有单调性),而是i个点之内。
总结:此题的关键在于对题目条件的转化。即将条件——>最值转化为以最值为条件(刚好为该值或以该值为界要具体看题目的需要)——>条件的最值,这样问题就变得可解多了。
这篇关于3971: circle的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!