1039 AlvinZH的学霸养成记IV

思路

难题,最大二分图匹配。

难点在于如何转化问题,n对n,一个只能攻击一个,判断是否存在一种攻击方案我方不死团灭对方。可以想到把所有随从看作点,对于可攻击的两个随从间连上边,这样就把问题转化为图了。

需要注意的是属性值的转化:免疫可看做生命值无限,剧毒可看做攻击力无限。(需要一点小小的机智)

图建好了,接下来怎么办呢?假设存在一种方案满足题意,那就是每个我方随从都可以找到敌方随从攻击,由于要团灭,只能存在一对一的情况,不存在多对一或一对多。如何表达这个方案呢?边!没错,就是刚才连起来的边的一个子集。这个子集有一个特点:n对n,n条边,边连着两边,且没有公共顶点。

没错,经过一番分析,最大二分图匹配已经很明显了。求解过程套板子就好了。

分析

二分图匹配算法

1.匈牙利算法:其本质就是,有条件就上,没条件创造条件也要上。DFS与BFS都可,时间复杂度均为 \(O(V⋅E)\) 。实际对于稀疏图BFS更佳。

2.Hopcroft-Karp算法:匈牙利算法的改进版,每次寻找多条增广路径。时间复杂度可以到达 \(O(n^{0.5}*m)\) 。

3.Dinic算法:二分图匹配其实是一个最大流问题,Dinic是一种优化过的求解最大流算法。与朴素的FF算法(\(O(n*m^2)\))不同,其可以同时多路增广。求解二分图时,构建超级源点和超级汇点,匹配边权值为1,求最大流即可。理论最坏复杂度为 \(O(n^2m)\) ,稠密图时比匈牙利DFS快了不少。

参考博客:二分图;

匈牙利算法;

Hopcroft-Karp算法;

Dinic算法

参考代码(DFS)

//
// Created by AlvinZH on 2017/11/27.
// Copyright (c) AlvinZH. All rights reserved.
// #include <cstdio>
#include <cstring>
#include <vector>
#define MaxSize 1005
#define INF 0x3f3f3f3f
using namespace std; int n, ans;
vector<int> G[MaxSize];//记录可攻击的敌方随从
int match[MaxSize];//记录匹配点
int visit[MaxSize];//记录是否访问 struct minion {
int attack, life;
}A[MaxSize], B[MaxSize]; bool dfs(int x)//寻找增广路径
{
for (int i = 0; i < G[x].size(); ++i)
{
int to = G[x][i];
if(!visit[to])
{
visit[to] = 1;
if(!match[to] || dfs(match[to]))
{
match[to] = x;
return true;
}
}
}
return false;
} int MaxMatch()
{
ans = 0;
memset(match, 0, sizeof(match));
for (int i = 1; i <= n; ++i)
{
memset(visit, 0, sizeof(visit));//清空访问
if(dfs(i)) ans++;//从节点i尝试扩展
}
return ans;
} int main()
{
while(~scanf("%d", &n))
{
int a, l, p;
for (int i = 1; i <= n; ++i) {
scanf("%d %d %d", &a, &l, &p); switch (p) {
case 0:
A[i].attack = a; A[i].life = l; break;
case 1:
A[i].attack = a; A[i].life = INF; break;
case 2:
A[i].attack = INF; A[i].life = l; break;
case 3:
A[i].attack = INF; A[i].life = INF; break;
default:
break;
}
}
for (int i = 1; i <= n; ++i)
scanf("%d %d", &B[i].attack, &B[i].life);
for (int i = 1; i <= n; ++i)
G[i].clear(); for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j) {
if(A[i].attack >= B[j].life && A[i].life > B[j].attack)
G[i].push_back(j);
}
}
if(n == MaxMatch()) printf("YES\n");
else printf("NO\n");
}
}

2016级算法第五次上机-E.AlvinZH的学霸养成记IV的更多相关文章

  1. 2016级算法第五次上机-D.AlvinZH的学霸养成记III

    850 AlvinZH的学霸养成记III 思路 难题.概率DP. 第一种思考方式:直接DP dp[i]:从已经有i个学霸到所有人变成学霸的期望. 那么答案为dp[1],需要从后往前逆推.对于某一天,有 ...

  2. 2016级算法第六次上机-F.AlvinZH的学霸养成记VI

    1082 AlvinZH的学霸养成记VI 思路 难题,凸包. 分析问题,平面上给出两类点,问能否用一条直线将二者分离. 首先应该联想到这是一个凸包问题,分别计算两类点的凸包,如果存在符合题意的直线,那 ...

  3. 2016级算法第六次上机-D.AlvinZH的学霸养成记V

    1081 AlvinZH的学霸养成记V 思路 中等题,计算几何. 这是一个排序问题,按极角排序.可以转化为叉积的应用,对于点A和B,通过叉积可以判断角度大小,共线时再判断距离. 叉积的应用.OA × ...

  4. 2016级算法第六次上机-C.AlvinZH的学霸养成记II

    1032 AlvinZH的学霸养成记II 思路 中等题,贪心. 所有课程按照DDL的大小来排序. 维护一个当前时间curTime,初始为0. 遍历课程,curTime加上此课程持续时间d,如果这时cu ...

  5. 2016级算法第五次上机-F.ModricWang的水系法术

    1066 ModricWang的水系法术 思路 比较典型的最大流问题,需要注意的是,题目已经暗示(明示)了这里的边是双向的,在建图的时候需要加上反向边的容量值. 解决最大流问题的基本思路就是不断在残量 ...

  6. 2016级算法第五次上机-C.Bamboo和"Coco"

    1064 Bamboo和"Coco" 分析题意 每个亡灵至少一个花瓣,相邻的亡灵中思念值高的要获得的花瓣高(思念值相等是不需要花瓣一样多的).主要考贪心思路,为了使得花瓣总量最少, ...

  7. 2016级算法第五次上机-B.Bamboo&APTX4844魔发药水

    Bamboo&APTX4844魔发药水 题意 "于是,Bamboo耐着性子,看巫师从袖子里掏出 M 瓶时光泉水和 K 粒绿色能量.每瓶时光泉水重量为 c ,生发效果为 l:每粒绿色能 ...

  8. 2016级算法第五次上机-A.Beihang Collegiate Pronunciation Contest 2017

    1065 Beihang Collegiate Pronunciation Contest 2017 思路 在字符串中不断做匹配 找到一个匹配就输出 时间复杂度\(O(n)\) ps.模式串是定长的, ...

  9. 2016级算法第五次上机-G.ModricWang的撒币游戏

    1062 ModricWang的撒币游戏 思路 此题为2017年ACM-ICPC亚洲区域赛乌鲁木齐赛区的A题,现场94个队中有38个队做出此题.在这里作为满分以外的题,是为了让大家看一下外面一些题的风 ...

随机推荐

  1. vpp命令总结

    create sub BondEthernet0 834 创建子接口,tag是834 set interface ip table BondEthernet0.834 1 将此接口设置在fib 1里 ...

  2. AID-应用标识符的组成规则

    AID:即唯一标识一个应用,分为两部分,RID(5字节)+PIX(最多11字节) RID:注册标识符,由ISO组织来分配,标识一个全球唯一的应用提供商,一般是分配给卡组织,比如分配给Master,比如 ...

  3. bootstrap导入JavaScript插件

    Bootstrap的JavaScript插件可以单独导入到页面中,也可以一次性导入到页面中.因为在Bootstrap中的JavaScript插件都是依赖于jQuery库,所以不论是单独导入还一次性导入 ...

  4. 假设字符串类似这样的aba和aab,abc和bca就相等,现在随便给你二组字符串,请编程比较他们看是否相等

    public static boolean stringSame(String str1,String str2){ if(str1.length() != str2.length()){//先判断长 ...

  5. C++11新特性之auto

    auto的使用  c++11引入了auto类型说明符,auto让编译器通过初始值来推算变量的类型,所以auto定义的变量必须有初始值.  使用auto也能在一条语句中声明多个变量,因为一条声明语句只能 ...

  6. Hadoop-2.4.0中HDFS文件块大小默认为128M

    134217728 / 1024 = 131072 / 1024 = 128

  7. Smart3d 近景摄影测量与航空摄影测量

    实例:http://blog.sina.com.cn/s/blog_8f68d2350102wef4.html ContextCapture(Smart3d):https://www.bentley. ...

  8. mybatis Mapper.xml和Mapper.java

    mybatis Mapper.xml和Mapper.java 通过Mapper.xml和Mapper.java来实现mybatis.环境和入门的一样的.关键:Mapper.xml + Mapper.j ...

  9. T4模板调用反射

    <#@ template debug="false" hostspecific="true" language="C#" #> ...

  10. modelsim使用常见问题及解决办法集锦 ②

    二.Error deleting “msim_transcript” Error deleting “msim_transcript”:permission denied. Check the Nat ...