题目背景

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. MFC中SliderCtrl控件的使用

    在MFC中滑动条(CSliderCtrl)是个经常使用的控件,使用方法例如以下: 主要要方法有: 1.设置.取得滑动范围: void SetRange( int nMin, int nMax, BOO ...

  2. memcached知识点梳理

    Memcached概念:    Memcached是一个免费开源的,高性能的,具有分布式对象的缓存系统,它可以用来保存一些经常存取的对象或数据,保存的数据像一张巨大的HASH表,该表以Key-valu ...

  3. hive时间

    Hive中日期函数总结:1.时间戳函数日期转时间戳:从1970-01-01 00:00:00 UTC到指定时间的秒数select unix_timestamp(); --获得当前时区的UNIX时间戳s ...

  4. python-----写入txt用法

    代码如下: #!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2019/1/14 11:23 # @Author : zxb file_p ...

  5. java io流读取 和commons.io的使用

    前提:记事本里面一共有605个字 1.使用BufferedReader和FileReader来读取txt里面的内容,用时相对短.读完记得关闭流br.close() 2.指定UTF-8输出格式,使用Fi ...

  6. 【Java】3到5年开发常见的Java面试题

    一.Java基础和高级 String类为什么是final的. HashMap的源码,实现原理,底层结构. 反射中,Class.forName和classloader的区别 session和cookie ...

  7. Using 10053 Trace Events and get outline

    When it comes to performance tuning, we can spend time on one or both ends of the problem. On the &q ...

  8. SCRIPT70: 没有权限

    主要原因:iframe安全而引发的问题,浏览器中js是没有垮域访问的权限的.如果用到iframe首先确保不垮域,或者不用iframe以绕开这个问题. 另外在jquery的早期版本中如:jquery-1 ...

  9. 专题七:UDP编程补充——UDP广播程序的实现

    一.程序实现 UDP广播程序的实现代码: using System; using System.Net; using System.Net.Sockets; using System.Text; us ...

  10. LN : leetcode 515 Find Largest Value in Each Tree Row

    lc 515 Find Largest Value in Each Tree Row 515 Find Largest Value in Each Tree Row You need to find ...