题目背景

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. 李维对VCL理解的几个错误

    研读深入浅出VCL一书的时候,有不少地方被网友提出疑问,而且似乎是网友们正确.但这丝毫不动摇李维在大中华Delphi界的江湖地位,因为高手应该是对整个系统理解的高手,而不是对某一个疑问的高手.能花巨量 ...

  2. Android 通过USB查看kernel调试信息【转】

    本文转载自:http://blog.csdn.net/lindonghai/article/details/51683644 前提:电脑已安装adb并可正常使用. 在调试Android驱动时,需要查看 ...

  3. mysql中decimal的使用

    float,double,decimal区别 创建表test_float_double_decimal CREATE TABLE `test_float_double_decimal` ( `id` ...

  4. URAL 1057 数位dp

    题目传送门http://acm.timus.ru/problem.aspx?space=1&num=1057 最近在学习数位dp,具体姿势可以参照这篇论文:http://wenku.baidu ...

  5. 10.04 FZSZ模拟Day1 总结

    今天轮到FZSZ出题了,这可是连续两年捧杯NOI的学校了…… 可想而知今天题难度有多大……不过似乎还要庆幸出题的是一位叫Anzhe Wang 的大神而不是fjzzq? T1.permutation 期 ...

  6. 【单独编译使用WebRTC的音频处理模块 - android】

    更新 [2015年2月15日] Bill 这段时间没有再关注 WebRTC 以及音频处理的相关信息,且我个人早已不再推荐单独编译 WebRTC 中的各个模块出来使用.实际上本文的参考价值已经很小了,甚 ...

  7. L1范数和L2范数

    给定向量x=(x1,x2,...xn)L1范数:向量各个元素绝对值之和L2范数:向量各个元素的平方求和然后求平方根Lp范数:向量各个元素绝对值的p次方求和然后求1/p次方L∞范数:向量各个元素求绝对值 ...

  8. js中setInterval() 和 setTimeout()

    setInterval() 方法 定义和用法 setInterval() 方法可按照指定的周期(以毫秒计)来调用函数或计算表达式. setInterval() 方法会不停地调用函数,直到 clearI ...

  9. C++中虚析构函数的作用 (转载)

    转自:http://blog.csdn.net/starlee/article/details/619827 我们知道,用C++开发的时候,用来做基类的类的析构函数一般都是虚函数.可是,为什么要这样做 ...

  10. HTML 5.1 -- 14项新增功能及如何使用

    最近太忙了 过完年来 连续的加班让我筋疲力尽,今天终于把东西交了,抽空来点干货吧! 1. 响应式图像 W3C 引入了一些功能特性,无需使用 CSS 就可以实现响应式图像.它们是 … srcset 图像 ...