连续攻击游戏

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

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

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

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

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

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

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

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

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

update 2024.5.13

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

hack数据:

3
1 2
1 2
2 3

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

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

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

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

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值