连续攻击游戏

这道题目其实就是上面一道“超级英雄”

这里将属性作为左部,装备作为右部就好了

其实我最开始是没有想到的,因为我一直在想把某一个对象作为二分图的节点

这道题目就启发我们,其实不是非要把一个对象作为二分图的节点的,我们还可以把两个对象分别作为二分图的左右部来考虑(转换对象法)

另外这道题目的N非常大,我们需要改善一下匈牙利算法,就是将vis数组改成int类型,然后在每次dfs的时候多加一个参数t,表示这是第几次dfs,然后在dfs里面判断vis是否等于t即可,这样就可以省去for循环的第一句memset了(注意dfs过程中vis不是加一,而是直接令成t

然后时间复杂度就正确了,可以从交错树的角度分析

注意交错树每一层的节点的属性都是相同的(指是左部节点还是右部节点),而且对于右部节点的层,每个节点只有唯一一个儿子,也就是说交错树的规模是左部节点的两倍,于是我们分析左部节点就好了,由于有vis标记,所以交错树的规模最多为10000,而最多寻找10000次增广路,于是时间复杂度就正确了(也就是说以后做二分图匹配的时候,让左部为数量更少的点的时间复杂度更优秀)

另外还有并查集解法,复习的时候做一下

思路正确性:对于没有环的连通块,我们任选p1个点,相当于任选一个点让其不能被选,将这个点作为树根,不难发现可以找到一种合法的分配方案;若连通块有环,可以将其看做基环树再加上若干条边,显然可以找到一种合法的分配方案;而每次合并让更大的点当根也是比较显然的贪心

update 2024.5.13

并查集做法的思路是对的,但是合并的时候代码是错的

hack数据:

3
1 2
1 2
2 3

错误原因也比较显然,就不赘述了

正确做法应该是记录点数和边数,只要边数不少于点数,那么就说明有环(注意这是一个连通集,没有环当且仅当边数为点数减一)

这个思路的来源就是转换对象法,将属性作为考虑对象,然后尝试转化为图论,由于只给了个属性值,就相当于告诉了边的起点和终点了(要对2这个数字敏感)

这题的并查集也算个经典模型吧,相当于把每条边要么分给其起点,要么分给其终点,只能分给一个点

posted @   最爱丁珰  阅读(9)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示