[模拟赛FJOI Easy Round #2][T3 skill] (最小割+最大权闭合子图(文理分科模型))
【题目描述】
天上红绯在游戏中扮演敏剑,对于高攻击低防御的职业来说,爆发力显得非常重要,为此,她准备学习n个技能,每个技能都有2个学习方向:物理攻击和魔法攻击。对于第i个技能,如果选择物理攻击方向,会增加ap_i的爆发力,如果选择魔法攻击的方向,会增加ad_i的爆发力。此外,还有一些combo,一个combo由两个技能组成,对于第i个combo,如果他们都是魔法攻击,会额外增加AD_i的爆发力,如果他们都是物理攻击,会额外增加AP_i的爆发力,如果他们不属于同一类型,会减少AX_i的爆发力。她找到了你,请你帮她选择技能的类型,产生最大的爆发力。(说明:每个技能都必须学习)
【输入数据】
第一行2个正整数n,m,表示技能的个数和combo的个数
接下来n行每行2个正整数,描述一个技能的ap_i,ad_i
接下来m行每行5个正整数u,v,AD_i,AP_i,AX_i,描述一个combo,表示技能u和技能v产生combo
【输出数据】
一行,一个整数,表示最大的爆发力
【样例输入】
【样例输出】
【样例解释】
均选择魔法攻击,获得5+20+100=125的爆发力
【数据范围】
测试点编号 |
n |
m |
1 |
5 |
5 |
2 |
50 |
100 |
3 |
100000 |
0 |
4 |
500000 |
0 |
5-7 |
1000 |
3000 |
8-10 |
10000 |
40000 |
对于所有的测试点,确保不会爆long long
Solution
模型:最小割,最大权闭合子图
来自出题者的题解:可以先看作我们把所有的技能的收益(不包括亏损AX)都获得了,然后在这个获益中扣除最小的代价
建图:
对于每个技能,建边(S,u,ap),(u,T,ad)
对于每个combo,拆点,对点一建边(S,buf1,AD),(buf1,u,+∞),(buf1,v,+∞)
对点二建边(buf2,T,AP),(u,buf2,+∞),(v,buf2,+∞)
跑个最大流算法就行
#include<stdio.h>
#include<limits.h>
#include<string.h>
#define LL long long
#define dmin(a,b) ((a)<(b)?(a):(b))
inline int Rin(){
int x=,c=getchar(),f=;
for(;c<||c>;c=getchar())
if(!(c^))f=-;
for(;c>&&c<;c=getchar())
x=(x<<)+(x<<)+c-;
return x*f;
}
const int N=;
const int M=;
const LL LINF=LONG_LONG_MAX/*;
LL tot();
int n,m,S,T,ecnt=,fst[N+M*];
struct edge{
int u,v,nxt;
LL cap,flow;
}e[(*M+*N)*];
inline void link(int x,int y,LL w){
e[++ecnt].u=x;e[ecnt].v=y;
e[ecnt].cap=w;e[ecnt].flow=;
e[ecnt].nxt=fst[x];fst[x]=ecnt;
e[++ecnt].u=y;e[ecnt].v=x;
e[ecnt].cap=;e[ecnt].flow=;
e[ecnt].nxt=fst[y];fst[y]=ecnt;
}
bool vis[N+M*];
int num[N+M*],cur[N+M*],d[N+M*],p[N+M*],q[N+M*];
void bfs(){
int hd=,tl=;
q[]=T;d[T]=;vis[T]=true;
while(hd^tl){
int now=q[hd++];
for(int j=fst[now];j;j=e[j].nxt)
if(!vis[e[j].u] && e[j].cap>e[j].flow)
vis[e[j].u]=true,
d[e[j].u]=d[now]+,
q[tl++]=e[j].u;
}
}
inline LL Agument(){
LL a=LINF;
int x=T;
while(x^S)
a=dmin(a,e[p[x]].cap-e[p[x]].flow),
x=e[p[x]].u;
x=T;
while(x^S)
e[p[x]].flow+=a,
e[p[x]^].flow-=a,
x=e[p[x]].u;
return a;
}
LL ISAP(){
int x(S);
LL flow();
bfs();
for(int i=S;i<=T;i++)num[d[i]]++;
for(int i=S;i<=T;i++)cur[i]=fst[i];
while(d[S]<T){
if(!(x^T))
flow+=Agument(),
x=S;
bool advanced=false;
for(int j=cur[x];j;j=e[j].nxt)
if(e[j].cap>e[j].flow && d[x]==d[e[j].v]+){
advanced=true;
cur[x]=j;
p[e[j].v]=j;
x=e[j].v;
break;
}
if(!advanced){
int mn=T-;
for(int j=fst[x];j;j=e[j].nxt)
if(e[j].cap>e[j].flow)
mn=dmin(mn,d[e[j].v]);
if(--num[d[x]]==)break;
num[d[x]=mn+]++;
cur[x]=fst[x];
if(x^S)x=e[p[x]].u;
}
}
return flow;
}
int main(){
freopen("skill.in","r",stdin);
freopen("skill.out","w",stdout);
n=Rin(),m=Rin();
S=,T=n++m*+;
for(int i=;i<=n;i++){
LL ap=Rin(),ad=Rin();
tot+=ap+ad;
link(S,i+,ap);
link(i+,T,ad);
}
for(int i=;i<=m;i++){
int u=Rin(),v=Rin();
LL AP=Rin(),AD=Rin(),AX=Rin();
tot+=AP+AD;
link(u+,v+,AX);
link(v+,u+,AX);
link(S,n++i,AD);
link(n++i,u+,LINF);
link(n++i,v+,LINF);
link(n++i+m,T,AP);
link(u+,n++i+m,LINF);
link(v+,n++i+m,LINF);
}
printf("%I64d\n",tot-ISAP());
fclose(stdin);
fclose(stdout);
return ;
}
[模拟赛FJOI Easy Round #2][T3 skill] (最小割+最大权闭合子图(文理分科模型))的更多相关文章
- [模拟赛FJOI Easy Round #2][T1 sign] (模拟+求字符串重复字串)
[题目描述] 小Z在无意中发现了一个神奇的OJ,这个OJ有一个神奇的功能:每日签到,并且会通过某种玄学的算法计算出今日的运势.在多次试验之后,小Z发现自己的运势按照一定的周期循环,现在他找到了你,请通 ...
- [NOI.AC省选模拟赛3.31] 附耳而至 [平面图+最小割]
题面 传送门 思路 其实就是很明显的平面图模型. 不咕咕咕的平面图学习笔记 用最左转线求出对偶图的点,以及原图中每个边两侧的点是谁 建立网络流图: 源点连接至每一个对偶图点,权值为这个区域的光明能量 ...
- 第 45 届国际大学生程序设计竞赛(ICPC)亚洲网上区域赛模拟赛. A.Easy Equation (前缀和/差分)
题意:RT,给你四个数\(a,b,c,d\),求\(x+y+z=k\)的方案数. 题解:我们可以先枚举\(x\)的值,然后\(x+y\)能取到的范围一定是\([x,x+b]\),也就是说这个区间内每个 ...
- [jzoj 4528] [GDOI2019模拟2019.3.26] 要换换名字 (最大权闭合子图)
题目链接: https://jzoj.net/senior/#contest/show/2683/0 题目: 题解: 不妨枚举一个点,让两颗树都以这个点为根,求联通块要么点数为$0$,要么包括根(即联 ...
- 2018 ACM-ICPC 中国大学生程序设计竞赛线上赛 F题 Clever King(最小割)
2018 ACM-ICPC 中国大学生程序设计竞赛线上赛:https://www.jisuanke.com/contest/1227 题目链接:https://nanti.jisuanke.com/t ...
- GDOI模拟赛Round 1
GDOI模拟赛Round 1 数据结构 题目描述:给出一个长度为\(n\)的序列,支持两种操作: 1.对某段区间都加上一个数 2.给出\(p.k\),求下面表示式对\((10^9+7)\)取模 \[\ ...
- @省选模拟赛03/16 - T3@ 超级树
目录 @description@ @solution@ @accepted code@ @details@ @description@ 一棵 k-超级树(k-SuperTree) 可按如下方法得到:取 ...
- 队爷的讲学计划 CH Round #59 - OrzCC杯NOIP模拟赛day1
题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的讲学计划 题解:刚开始理解题意理解了好半天,然后发 ...
- 队爷的Au Plan CH Round #59 - OrzCC杯NOIP模拟赛day1
题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的Au%20Plan 题解:看了题之后觉得肯定是DP ...
随机推荐
- matlab采用mex编译多个cpp文件
最近在看matlab code时,由于本人使用的是64系统,而code中的mex文件时在32位系统上编译的,所以需要重新自己编译maxflowmex.cpp,但是直接mex maxflowmex.cp ...
- iOS开发——多线程
很多朋友都说iOS开发中,最难理解和学习的就是多线程,很多的原理实现都是通过log看到,也比较抽象,本人也是在多线程方面投入过很多脑细胞..无论这方面的知识掌握和应用起来是否轻松,牢固的基本功.正确的 ...
- query或者JavaScript实现在textarea光标处插入文本
1.Jquery函数实现: $(function() { /* 在textarea处插入文本--Start */ (function($) { $.fn.extend({ insertContent ...
- bzoj 1652: [Usaco2006 Feb]Treats for the Cows【区间dp】
裸的区间dp,设f[i][j]为区间(i,j)的答案,转移是f[i][j]=max(f[i+1][j]+a[i](n-j+i),f[i][j-1]+a[j]*(n-j+i)); #include< ...
- bzoj1880: [Sdoi2009]Elaxia的路线(spfa,拓扑排序最长路)
1880: [Sdoi2009]Elaxia的路线 Time Limit: 4 Sec Memory Limit: 64 MBSubmit: 1944 Solved: 759[Submit][St ...
- php 文件上传限制修改
修改PHP上传文件大小限制的方法 1. 一般的文件上传,除非文件很小.就像一个5M的文件,很可能要超过一分钟才能上传完.但在php中,默认的该页最久执行时间为 30 秒.就是说超过30秒,该脚本就停止 ...
- Linux下安装网络软件的步骤
Linux下安装网络软件的步骤(给linux初学者,linux大神请绕路) 首先下载你所需要的软件带有deb后缀的文件 然后切换到该文件的目录 切换到超级用户权限或者是(sudo) 使用sudo dp ...
- C#和C++的区别(一)
C#特性 1.指针可以有++.--运算,引用不可以运算: 2.类或结构的默认访问类型是internal 类的所有成员,默认是private 3.属性:用于定义一些命名特性,通过它来读取和写入相关的特性 ...
- P1400 塔
题目描述 有N(2<=N<=600000)块砖,要搭一个N层的塔,要求:如果砖A在砖B上面,那么A不能比B的长度+D要长.问有几种方法,输出 答案 mod 1000000009的值. 输入 ...
- Table标题行冻结,数据行滚动的一种方式
这段时间在做Table标题行冻结,数据行滚动,虽然能实现,但也遇到一些问题,记录下来. 首先说说实现,实现其实不难,估计很多人都能想象出来,那就是标题行与内容行分离.我是这么做的,用两个表格,一个只有 ...