题目背景

byx和手气君都非常都非常喜欢种树。有一天,他们得到了两颗奇怪的树种,于是各自取了一颗回家种树,并约定几年后比一比谁种出来的树更加牛x。

题目描述

很快,这棵树就开花结果了。byx和手气君惊讶的发现,这是一棵主席树,树上长满了主席和主席的朋友们。这棵树上一共有五种人,主席(J),记者(HK),高人(W),女王(E)和膜法师(YYY)。他们发现,他们的主席树上的人数相同,都为N。

研究发现,这五种人的输赢如上图所示(一样的人不能PK),箭头指向输的人。至于为什么,留给同学们自己思考。

比赛如期进行。

byx和手气君要进行M场比赛,每一场比赛他们会选出树上的两个人来比较看谁更牛x。

第i个人寿命为Lifei秒,每次比完赛他们就会-1s。当他们生命为0s时他们就不能再比赛了。

同时,当J的寿命为0时,同一棵树上的YYY可以为他+1s。每个YYY只能给.每个J续一次。

那么问题来了

现在给定N,M(1≤N≤100,1≤M≤1000),A和B每一个人所属种类(J,HK,W,YYY或E)以及每一个人的生命,生命不超过50.请你算算A最多能够赢得多少场比赛呢。

数据保证每一场一定都有人用。两个人之间只能比一场。

输入输出格式

输入格式:

第一行包含两个数N,M,含义看上面。

第二行N个字串(J,HK,W,YYY或E),表示byx的人所属种类,用空格隔开。

第三行N个字串(J,HK,W,YYY或E),表示手气君的人所属种类,用空格隔开。

第四行N个数,表示byx的人的生命。

第五行N个数,表示手气君的人的生命。

输出格式:

一个数,byx能赢的场次

输入输出样例

输入样例#1:

3 3
J W YYY
J HK E
2 2 2
2 2 2
输出样例#1:

3

说明

第一场主席赢记者,第二场高人赢女王,第三场膜法师赢记者。

Solution:

  本题最大流。

  读完题后,不难发现是一张二分图的模型,而且角色克制关系也给定了,那么就是个傻逼建图了。

  我们由源点向byx的每个人连边流量为生命值,由手气君的每个人向汇点连边流量为生命值,对于byx的每个节点按照击败关系向手气君的节点连边流量为$1$,由于$YYY$可以为每个$J$加血,所以统计下byx和手气君各自的$YYY$个数,再对于各自的$J$都补建$YYY$个数为流量的边就好了。(开始WA的原因:注意不能直接统计角色总血量然后对每种角色建图,因为两个角色之间只能比一次,而且每个$YYY$可以为每个$J$加一次血,都有流量限制,所以只能$n^2$建图)

代码:

/*Code by 520 -- 9.25*/
#include<bits/stdc++.h>
#define il inline
#define ll long long
#define RE register
#define For(i,a,b) for(RE int (i)=(a);(i)<=(b);(i)++)
#define Bor(i,a,b) for(RE int (i)=(b);(i)>=(a);(i)--)
using namespace std;
const int N=,inf=;
int n,m,s,t,dis[],a[],b[];
int to[N],net[N],w[N],cnt=,h[N];
map<string,int>mp; il void add(int u,int v,int c){
to[++cnt]=v,net[cnt]=h[u],h[u]=cnt,w[cnt]=c;
to[++cnt]=u,net[cnt]=h[v],h[v]=cnt,w[cnt]=;
} queue<int>q;
bool bfs(){
memset(dis,-,sizeof(dis));
dis[s]=,q.push(s);
while(!q.empty()){
RE int u=q.front();q.pop();
for(RE int i=h[u];i;i=net[i])
if(w[i]&&dis[to[i]]==-) dis[to[i]]=dis[u]+,q.push(to[i]);
}
return dis[t]!=-;
} int dfs(int u,int op){
if(u==t) return op;
int flow=,used=;
for(RE int i=h[u];i;i=net[i]){
int v=to[i];
if(w[i]&&dis[to[i]]==dis[u]+){
used=dfs(to[i],min(w[i],op));
if(!used) continue;
flow+=used,op-=used;
w[i]-=used,w[i^]+=used;
if(!op) break;
}
}
if(!flow) dis[u]=-;
return flow;
} int main(){
scanf("%d%d",&n,&m),t=;
mp["J"]=,mp["HK"]=,mp["W"]=,mp["YYY"]=,mp["E"]=;
string ca[],cb[];int na[],nb[];
int ta=,tb=;
For(i,,n) cin>>ca[i];
For(i,,n) cin>>cb[i];
For(i,,n) {
cin>>na[i],add(s,i,na[i]);
if(mp[ca[i]]==) ta++;
}
For(i,,n) {
cin>>nb[i],add(i+,t,nb[i]);
if(mp[cb[i]]==) tb++;
}
For(i,,n) {
if(mp[ca[i]]==) add(s,i,ta);
if(mp[cb[i]]==) add(i+,t,tb);
}
For(i,,n) For(j,,n){
int p=mp[ca[i]],q=mp[cb[j]];
if(p==&&(q==||q==)) add(i,j+,);
if(p==&&(q==||q==)) add(i,j+,);
if(p==&&(q==||q==)) add(i,j+,);
if(p==&&(q==||q==)) add(i,j+,);
if(p==&&(q==||q==)) add(i,j+,);
}
int ans=;
while(bfs()) ans+=dfs(s,inf);
cout<<min(ans,m);
return ;
}

P3701 「伪模板」主席树的更多相关文章

  1. [Luogu] P3701 「伪模板」主席树

    题目背景 byx和手气君都非常都非常喜欢种树.有一天,他们得到了两颗奇怪的树种,于是各自取了一颗回家种树,并约定几年后比一比谁种出来的树更加牛x. 题目描述 很快,这棵树就开花结果了.byx和手气君惊 ...

  2. [洛谷P3701]「伪模板」主席树

    题目大意:太暴力了,就不写了,看这儿 题解:对于每个$byx$的人,从源点向人连边,容量为此人的寿命. 对于每个手气君的人,从人向汇点连边,容量为此人的寿命. 对于每个$byx$的人与手气君的人,如果 ...

  3. [Luogu 3701] 「伪模板」主席树

    [Luogu 3701] 「伪模板」主席树 这是一道网络流,不是主席树,不是什么数据结构,而是网络流. 题目背景及描述都非常的暴力,以至于 Capella 在做此题的过程中不禁感到生命流逝. S 向 ...

  4. 【luoguP3701】「伪模板」主席树

    description byx和诗乃酱都非常都非常喜欢种树.有一天,他们得到了两颗奇怪的树种,于是各自取了一颗回家种树,并约定几年后比一比谁种出来的树更加牛x. 很快,这棵树就开花结果了.byx和诗乃 ...

  5. LuoguP3701 「伪模板」主席树

    题面 这个题很有意思啊... 其实是道最大流板子题,只连byx会赢的边,S向byx连,另一个连T... 注意有长者时连的边加上同方mogician的个数... 还要注意mogician可以无限续命,也 ...

  6. 「模板」 线段树——区间乘 && 区间加 && 区间求和

    「模板」 线段树--区间乘 && 区间加 && 区间求和 原来的代码太恶心了,重贴一遍. #include <cstdio> int n,m; long l ...

  7. 「WC 2019」数树

    「WC 2019」数树 一道涨姿势的EGF好题,官方题解我并没有完全看懂,尝试用指数型生成函数和组合意义的角度推了一波.考场上只得了 44 分也暴露了我在数数的一些基本套路上的不足,后面的 \(\ex ...

  8. 【题解】#6622. 「THUPC 2019」找树 / findtree(Matrix Tree+FWT)

    [题解]#6622. 「THUPC 2019」找树 / findtree(Matrix Tree+FWT) 之前做这道题不理解,有一点走火入魔了,甚至想要一本近世代数来看,然后通过人类智慧思考后发现, ...

  9. 【Luogu】P3384主席树模板(主席树查询K小数)

    YEAH!我也是一个AC主席树模板的人了! 其实是个半吊子 我将尽量详细的讲出我的想法. 主席树太难,我们先搞普通线段树好了 普通线段树怎么做?我的想法是查询K次最小值,每次查完把查的数改成INF,查 ...

随机推荐

  1. c语言数字图像处理(六):二维离散傅里叶变换

    基础知识 复数表示 C = R + jI 极坐标:C = |C|(cosθ + jsinθ) 欧拉公式:C = |C|ejθ 有关更多的时域与复频域的知识可以学习复变函数与积分变换,本篇文章只给出DF ...

  2. 基于Redis实现分布式锁(续)

    代码实现: redis实现分布式锁(lock:通过间隔时间段去请求Redis,来实现阻塞占用,一直到获取锁,或者超时. unlock:删除redis中key)

  3. ossec安装

    安装 安装要求 对于Unix系统来说,OSSEC只需要GNU的make.gcc和libc.推荐使用OpenSSL,但仅属于一个可选项.而且,通常您只需在一个系统上做编译操作,然后将二进制程序复制到其他 ...

  4. OSSEC 架构

    OSSEC由很多部分组成,它有一个集中的管理端,用于监控.并接收来自代理.syslog.数据库或无代理设备的日志. 管理端(服务器) 管理端属于OSSEC部署中的中心部分.它存储了文件完整性检测数据库 ...

  5. java基础学习总结——线程(二)

    一.线程的优先级别

  6. Python20-Day06

    常用模块 一.random模块 import random # print(random.random()) #打印0-1之间的小数 # print(random.randint(1,3)) #大于等 ...

  7. [java] jar file

    查看 .jar 内的文件 jar tf jarfile.jar maven 项目中, java 读取目标文件 运行 mvn package 打包项目是, src/main/resources 下的文件 ...

  8. 构造一个简单的Linux内核的MenuOS

    构造一个简单的Linux内核的MenuOS 20135109 高艺桐 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000 ...

  9. 实验三:跟踪分析Linux内核的启动过程

    实验三:跟踪分析Linux内核的启动过程 学号:20135114 姓名:王朝宪 注: 原创作品转载请注明出处   <Linux内核分析>MOOC课程http://mooc.study.16 ...

  10. Shell脚本 数据清洗

    需要做的任务是将上图类似的格式的文件进行处理,将年月日小时分别提取出来放到每行的行尾(上图已清洗好) 自己的思路是先用cut命令将每行的年月日小时提取出来,分别给一个变量,然后再循环利用sed命令将年 ...