【集训试题】exam 信心考 最小割
题意概述:
有N个人,A,B两个考场。如果学生i在A考场,总信心值增加xi;如果学生i在B考场,总信心值增加yi。其中还有m对好友,当第i对好友的两个人都在A考场时,总信心值增加ai;如果两人都在B考场,总信心值增加bi;如果两个人在不同考场,那么总信心值减少ci。
问总信心值最大能达到多少(总信心值的初始值为0)。
N<=10000,M<=50000,time limit = 1s
分析:
这类最小割问题非常经典,一般都是有两个集合,每个元素属于某个集合可以得到某种收益,同时还会有一些两个元素之间的关系,比如被分到同一个集合或者不同集合需要付出的代价/得到的收益等等。思路是首先我们将所有的收益全部加起来,假设我们得到了所有的收益,然后建图跑最小割求我们需要付出的最小代价,最大收益=所有可能的收益-最小代价。
说一下此题的建图,此题本身选择就可能产生代价,因此把代价看成收益。假设我们一开始从获得的总收益为,所有的x,y,a,b,c的和。
令s代表B考场,t代表A考场,s向所有考生连边容量为yi,当这条边被割掉的时候考生i被选入A考场,付出代价yi;所有考生向t连一条边容量为xi,意义同上;所有的朋友之间,s向两个点分别连边,容量为(b+c)/2,当这两条边被一起割掉的时候他们都在A考场,付出代价b+c;两个点向t连边,意义类似;两个点之间连一条容量为(a+b+2c)/2,当两个考生在不同考场的时候(在网络意义下他们不连通)这条边被割掉,这对朋友一共付出代价a+b+2c。
跑最小割即可,因为建图的时候涉及到除以二的问题所以先把所有的边容量乘以2,最后把这个2除回来即可。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<cctype>
#define inf 9e18
using namespace std;
const int maxn=;
const int maxm=;
typedef long long LL; int N,M,A[maxn],B[maxn],S,T,tot;
struct data{ int u,v,a,b,c; }C[maxm];
struct net_edge{ int from,to,next; LL cap,flow; }NE[*maxn+*maxm];
int nfirst[maxn],nnp,cur[maxn],fl[maxn],d[maxn],gap[maxn];
int mq[maxn],front,rear; void _scanf(int &x)
{
x=;
char ch=getchar();
while(ch<''||ch>'') ch=getchar();
while(ch>=''&&ch<='') x=x*+ch-'',ch=getchar();
}
void data_in()
{
_scanf(N);_scanf(M);
for(int i=;i<=N;i++) _scanf(A[i]);
for(int i=;i<=N;i++) _scanf(B[i]);
for(int i=;i<=M;i++){
_scanf(C[i].u);_scanf(C[i].v);
_scanf(C[i].a);_scanf(C[i].b);_scanf(C[i].c);
}
}
void net_add_edge(int u,int v,LL cap)
{
NE[++nnp]=(net_edge){u,v,nfirst[u],cap,};
nfirst[u]=nnp;
NE[++nnp]=(net_edge){v,u,nfirst[v],,};
nfirst[v]=nnp;
}
void _net_add_edge(int u,int v,LL cap)
{
NE[++nnp]=(net_edge){u,v,nfirst[u],cap,};
nfirst[u]=nnp;
NE[++nnp]=(net_edge){v,u,nfirst[v],cap,};
nfirst[v]=nnp;
}
void build_net()
{
S=N+,T=N+,tot=T;
for(int i=;i<=N;i++){
net_add_edge(S,i,(LL)*B[i]);
net_add_edge(i,T,(LL)*A[i]);
}
int u,v;
for(int i=;i<=M;i++){
u=C[i].u,v=C[i].v;
net_add_edge(S,u,(LL)C[i].b+C[i].c);
net_add_edge(u,T,(LL)C[i].a+C[i].c);
net_add_edge(S,v,(LL)C[i].b+C[i].c);
net_add_edge(v,T,(LL)C[i].a+C[i].c);
_net_add_edge(u,v,(LL)C[i].a+C[i].b+(LL)*C[i].c);
}
}
void BFS(int s)
{
for(int i=;i<=tot;i++) d[i]=tot;
front=rear=;
mq[rear++]=s;
d[s]=;
int i,j;
while(front!=rear){
i=mq[front++];
for(int p=nfirst[i];p;p=NE[p].next){
j=NE[p].to;
if(d[j]==tot) d[j]=d[i]+,mq[rear++]=j;
}
}
}
LL augment(int s,int t)
{
int now=t; LL flow=inf;
while(now!=s){
flow=min(flow,NE[fl[now]].cap-NE[fl[now]].flow);
now=NE[fl[now]].from;
}
now=t;
while(now!=s){
NE[fl[now]].flow+=flow,NE[(fl[now]-^)+].flow-=flow;
now=NE[fl[now]].from;
}
return flow;
}
LL ISAP(int s,int t)
{
memcpy(cur,nfirst,sizeof(cur));
BFS(t);
for(int i=;i<=tot;i++) gap[d[i]]++;
LL maxflow=; int now=s,j;
while(d[s]<tot){
if(now==t){
maxflow+=augment(s,t);
now=s;
}
bool ok=;
for(int p=cur[now];p;p=NE[p].next){
j=NE[p].to;
if(d[j]+==d[now]&&NE[p].cap>NE[p].flow){
ok=;
cur[now]=fl[j]=p;
now=j;
break;
}
}
if(!ok){
int minl=tot;
for(int p=nfirst[now];p;p=NE[p].next){
j=NE[p].to;
if(d[j]+<minl&&NE[p].cap>NE[p].flow) minl=d[j]+;
}
if(--gap[d[now]]==) break;
gap[d[now]=minl]++;
cur[now]=nfirst[now];
if(now!=s) now=NE[fl[now]].from;
}
}
return maxflow;
}
void work()
{
build_net();
LL sum=;
for(int i=;i<=N;i++) sum+=A[i],sum+=B[i];
for(int i=;i<=M;i++)
sum+=C[i].a,sum+=C[i].b,sum+=C[i].c;
cout<<sum-ISAP(S,T)/<<'\n';
}
int main()
{
data_in();
work();
return ;
}
【集训试题】exam 信心考 最小割的更多相关文章
- [2016北京集训试题6]网络战争-[最小割树(网络流)+kd-tree+倍增]
Description A 联邦国有 N 个州,每个州内部都有一个网络系统,有若干条网络线路,连接各个 州内部的城市. 由于 A 国的州与州之间的关系不是太好,每个州都只有首府建立了到别的州的网络.具 ...
- LOJ6045 雅礼集训 2017 Day8 价(最小割)
由Hall定理,任意k种减肥药对应的药材数量>=k.考虑如何限制其恰好为k,可以将其看作是使对应的药材数量尽量少. 考虑最小割.建一个二分图,左边的点表示减肥药,右边的点表示药材.减肥药和其使用 ...
- LOJ_6045_「雅礼集训 2017 Day8」价 _最小割
LOJ_6045_「雅礼集训 2017 Day8」价 _最小割 描述: 有$n$种减肥药,$n$种药材,每种减肥药有一些对应的药材和一个收益. 假设选择吃下$K$种减肥药,那么需要这$K$种减肥药包含 ...
- LOJ#6045. 「雅礼集训 2017 Day8」价(最小割)
题面 传送门 题解 首先先把所有权值取个相反数来求最大收益,因为最小收益很奇怪 然后建图如下:\(S\to\)药,容量\(\inf+p_i\),药\(\to\)药材,容量\(\inf\),药材\(\t ...
- P3749 [六省联考2017]寿司餐厅 最小割
\(\color{#0066ff}{ 题目描述 }\) Kiana 最近喜欢到一家非常美味的寿司餐厅用餐. 每天晚上,这家餐厅都会按顺序提供 \(n\) 种寿司,第 \(i\) 种寿司有一个代号 \( ...
- (2016北京集训十三)【xsy1532】网络战争 - 最小割树+树上倍增+KD树
题解: 好题!! 这题似乎能上我代码长度记录的前五? 调试时间长度应该也能上前五QAQ 首先题目要求的明显就是最小割,当然在整个森林上求Q次最小割肯定是会GG的,所以我们需要一个能快速求最小割的算法— ...
- P5934-[清华集训2012]最小生成树【最小割】
正题 题目链接:https://www.luogu.com.cn/problem/P5934 题目大意 给出\(n\)个点\(m\)条边的一张图,再加入一条边\((u,v,L)\)求至少删掉多少条边可 ...
- 最小割&网络流应用
重要链接 基础部分链接 : 二分图 & 网络流初步 zzz大佬博客链接 : 网络流学习笔记 重点内容:最小割二元关系新解(lyd's ppt) 题目:网络流相关题目 lyd神犇课件链接 : 网 ...
- 最大流&最小割 - 专题练习
[例1][hdu5889] - 算法结合(BFS+Dinic) 题意 \(N\)个点\(M\)条路径,每条路径长度为\(1\),敌人从\(M\)节点点要进攻\(1\)节点,敌人总是选择最优路径即最短路 ...
随机推荐
- Mac 使用问题
Mac 使用 Mac改变系统截图存储位置 鼠标在屏幕中间上下滚动时,有时反应不灵敏: 看看偏好设置-> 鼠标 -> 跟踪速度或者手势部分是否有哪里设置不当: 考虑重新开启鼠标鼠标底部有一个 ...
- js动画之requestAnimationFrame
1.setTimeout和setInterval 在讲setTimeout和setInterval之前,先讲一下异步执行的运行机制.(同步执行也是如此,因为它可以被视为没有异步任务的异步执行.) (1 ...
- MySQL存储引擎与索引
引言: MySQL存储引擎主要分为 InnoDB 存储引擎与 MyISAM 存储引擎.都采用B+数的存储结构. 应用场景: InnoDB适合:(1)可靠性要求比较高,要求事务:(2)大量 insert ...
- 菜鸟笔记 -- Chapter 6.2.1 权限修饰符
6.2.1 权限修饰符 面向对象的三大特性就有封装,封装隐藏了对象的属性和实现细节,仅对外提供公共访问方式,而这个访问方式就是由权限修饰符控制的.Java中的权限修饰符主要包括private.pub ...
- GET&&POST请求编码过程
编码.解码 我们在开发过程中不可避免的一个话题就是编码和解码,那么什么是编码什么是解码呢?为什么要进行编码和解码呢?下面我们一一分析! 编码和解码的概念 编码是信息从一种形式或格式转换为另一种形式的过 ...
- 判断js中数据类型 的最短代码
判断字符串类型的: function isString(obj) { return obj+"" === obj; } 判断bool类型的: function isBool(obj ...
- 2、开发环境搭建-window平台
一.搭建ReactNative环境 首先安装node.js和python2.xx版本,不要装python3.xx,这个官方是特别说明的,请注意.NodeJs官方下载:https://nodejs.or ...
- 第13届景驰-埃森哲杯广东工业大学ACM程序设计大赛--K-密码
链接:https://www.nowcoder.com/acm/contest/90/K 来源:牛客网 - 1.题目描述 ZiZi登录各种账号的时候,总是会忘记密码,所以他把密码都记录在一个记事本上. ...
- 路由器基础配置之广播多路访问链路上的ospf
我们将以上面的拓扑图进行实验,因为是要以不断广播的形式进行ospf,所有中间加了一个集线器,这种ospf和前一种不同,路由器之间会在配置好ospf之后选举出一个老大,DR,一个备份,BDR,而其他路由 ...
- 日志管理——rsyslog
官方文档(必看) http://www.rsyslog.com/doc/v8-stable/ 简介 rsyslog是linux自带日志管理工具,分为客户端\服务端,包含日志收集\过滤\分析\转储. 数 ...