题目背景

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最多能够赢得多少场比赛呢。

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

题目解析

其实没有那么难吧

最大流

S向byx的人连边,边权是寿命。手气君的人向T连边,边权是寿命。

如果byx的人向ta能战胜的手气君的人连边,边权是1。

然后DINIC

不过貌似什么地方写挂了,只有90。完了再填坑吧

Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std; const int MAXN = + ;
const int MAXM = + ;
const int S = ;
const int T = ;
const int INF = 0x3f3f3f3f; struct Tree {
string name;
int life;
} a[MAXN],b[MAXN];
struct Edge {
int nxt;
int to,w;
} l[MAXN*MAXN*]; int n,m;
int maxflow;
int num[];
int head[MAXN*],cnt=;
int deep[MAXN*],cur[MAXN*]; inline void add(int x,int y,int z) {
cnt++;
l[cnt].nxt = head[x];
l[cnt].to = y;
l[cnt].w = z;
head[x] = cnt;
return;
} inline void build() {
for(int i = ;i <= n;i++) {
add(S,i,a[i].life);add(i,S,);
add(i+n,T,b[i].life);add(T,i+n,);
}
for(int i = ;i <= n;i++) {
for(int j = ;j <= n;j++) {
if(a[i].name == "W" && (b[j].name == "YYY" || b[j].name == "E")) add(i,j+n,),add(j+n,i,);
else if(a[i].name == "HK" && (b[j].name == "W" || b[j].name == "E")) add(i,j+n,),add(j+n,i,);
else if(a[i].name == "E" && (b[j].name == "J" || b[j].name == "YYY")) add(i,j+n,),add(j+n,i,);
else if(a[i].name == "YYY" && (b[j].name == "J" || b[j].name == "HK")) add(i,j+n,),add(j+n,i,);
else if(a[i].name == "J" && (b[j].name == "W" || b[j].name == "HK")) add(i,j+n,),add(j+n,i,);
}
}
return;
}
queue<int> Q;
inline bool bfs(){
memset(deep,,sizeof(deep));
while(Q.size()) Q.pop();
deep[S]=;Q.push(S);
while(Q.size()){
int x=Q.front();Q.pop();
for(register int i=head[x];i;i=l[i].nxt){
int u=l[i].to;
if(!deep[u] && l[i].w){
deep[u]=deep[x]+;
if(u==T) return true;
Q.push(u);
}
}
}
return false;
} int dfs(int x,int flow){
if(x==T) return flow;
int res=flow,k;
for(register int i=head[x];i && res;i=l[i].nxt){
int u=l[i].to;
if(l[i].w && deep[u]==deep[x]+){
k=dfs(u,min(l[i].w,res));
if(!k) deep[u]=;
l[i].w -= k;
res-=k;
}
}
return flow-res;
} inline void Dinic(int s,int t) {
while(bfs()) maxflow += dfs(s,INF);
return;
} int main() {
scanf("%d%d",&n,&m);
for(int i = ;i <= n;i++) {
cin>>a[i].name;
if(a[i].name == "YYY") num[]++;
}
for(int i = ;i <= n;i++) {
cin>>b[i].name;
if(b[i].name == "YYY") num[]++;
}
for(int i = ;i <= n;i++) {
scanf("%d",&a[i].life);
if(a[i].name == "J") a[i].life += num[];
}
for(int i = ;i <= n;i++) {
scanf("%d",&b[i].life);
if(b[i].name == "J") b[i].life += num[];
}
build();
Dinic(S,T);
int debug = min(m,maxflow);
if(debug == ) debug += ;//QAQ
printf("%d",debug);
return ;
}

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

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

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

  2. P3701 「伪模板」主席树

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

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

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

  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. [Unity-21] Prefab具体解释

    1.什么是Prefab? Prefab又被称为预设,以下部分来自官网:预置是一种资源类型--存储在项目视图中的一种可反复使用的游戏对象.预置能够多次放入到多个场景中. 当你加入一个预置到场景中,就创建 ...

  2. 【Silverlight】Bing Maps学习系列(二):通过Bing Maps Silverlight Control如何显示地图(转)

    [Silverlight]Bing Maps学习系列(二):通过Bing Maps Silverlight Control如何显示地图 如本系列第一篇你所介绍的,开发基于Silverlight的Bin ...

  3. 埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛 C序列变换

    链接:https://www.nowcoder.com/acm/contest/91/C来源:牛客网没有账号的同学这样注册,支持博主 题目描述 给定两个长度为n的序列,ai, bi(1<=i&l ...

  4. BZOJ_1229_[USACO2008 Nov]toy 玩具_三分+贪心

    BZOJ_1229_[USACO2008 Nov]toy 玩具_三分+贪心 Description 玩具 [Chen Hu, 2006] Bessie的生日快到了, 她希望用D (1 <= D ...

  5. werkzeug 详解

    首先,先向大家介绍一下什么是 werkzeug,Werkzeug是一个WSGI工具包,他可以作为一个Web框架的底层库.这里稍微说一下, werkzeug 不是一个web服务器,也不是一个web框架, ...

  6. python-----利用filecmp删除重复文件

    以下代码素材自取:链接:https://pan.baidu.com/s/1fL17RjKyGjpvpeeUFONCaQ  提取码:zgiw # coding:utf-8 import os impor ...

  7. 基于.Net Core的API框架的搭建(3)

    5.加入缓存支持 我们希望为项目增加缓存支持,我们选择Redis做为缓存数据库. 首先,我们在Services目录增加一个缓存接口类ICacheService: using System; using ...

  8. C#与C++的区别(二)

    这几天深入学习C#的面向对象的内容,发现C#的很多用法跟C++比起来还是有很多的不同点,头脑中知识的海洋刮起了阵阵海浪,在此继续整理一下二者的不同点,主要还是写的C#能用,而在C++中不能用的一些知识 ...

  9. php 页面展示

    php 页面展示 复杂逻辑. 段落注释

  10. 400 Nth Digit 第N个数字

    在无限的整数序列 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ...中找到第 n 个数字.注意:n 是正数且在32为整形范围内 ( n < 231).示例 1:输入:3 ...