【BZOJ-1449&2895】球队收益&球队预算 最小费用最大流
1449: [JSOI2009]球队收益
Time Limit: 5 Sec Memory Limit: 64 MB
Submit: 648 Solved: 364
[Submit][Status][Discuss]
Description

Input

Output
Sample Input
1 0 2 1
1 1 10 1
0 1 3 3
1 2
2 3
3 1
Sample Output
HINT

Source
2895: 球队预算
Time Limit: 10 Sec Memory Limit: 256 MB
Submit: 51 Solved: 50
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
1 0 2 1
1 1 10 1
0 1 3 3
1 2
2 3
3 1
Sample Output
Data Limit
对于20%的数据2<=n<=10,0<=m<=20
对于100%的数据2<=n<=5000,0<=m<=1000,0<=di<=ci<=10,0<=a[i],b[i]<=50.
HINT
Source
Solution
idea很好的建图,不能考虑直接建,而应该利用增量的思想
个人的想法是这样的:
源到各比赛连边,容量为1,费用为0
建每个球队分成两个,由个比赛连向两只球队a,b,再由a连b',b连a',分别表示a赢了这场比赛或b赢了这场比赛
然后由各个点i'连向汇容量为inf,费用为0
然后预处理出来已比完的比赛胜负的价值,加上最小费用即可;
思路是考虑一场比赛的胜负对于结果的贡献,从这场比赛结束后对结果的增量来考虑,但显然这种方法并不是很优,但理论上可A
那么同样的思想,换一种方法建图:
不妨先假设后面的M场比赛中双方都是输家,这样我们只要在模型中表示一方成为赢家即可。
此应该有一个初步的模型了:对于N支球队和M场比赛各建一个点,从源向每场比赛连流量1费用0的边,从比赛向参与这场比赛的两支队伍各连一条流量1费用0的边。剩下的就是队伍收益的费用表示了。
多赢一场比赛产生的收益。即(C*(w+1)^2+D*(l-1)^2)-(C*w^2+D*l^2)=2w*C-2l*D+C+D。对于第i支队伍,假设后M场中i参加的有x场,那么最初w=win,l=lose+x,之后每赢一场w++,l--。我们从第i支队伍的点向汇连x条边,分别代表第i支队伍赢了j场比赛时相对赢j-1场时收益的增量。由于增量一定越来越大(平方嘛),所以流量最先流过的一定是费用较小的边,即j最小的边。
-----by huzecong
Code
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
using namespace std;
int read()
{
int x=,f=; char ch=getchar();
while (ch<'' || ch>'') {if (ch=='-')f=-; ch=getchar();}
while (ch>='' && ch<='') {x=x*+ch-''; ch=getchar();}
return x*f;
}
#define maxn 5100+1100
#define maxm 100100
int n,m,ans,S,T,num[];
struct Teamnode{int win,lose,C,D;}team[];
struct Edgenode{int to,next,cap,cost,from;}edge[maxm];
int head[maxn],cnt=;
void add(int u,int v,int w,int c)
{cnt++;edge[cnt].from=u;edge[cnt].to=v;
edge[cnt].next=head[u];head[u]=cnt;
edge[cnt].cost=c;edge[cnt].cap=w;}
void insert(int u,int v,int w,int c){add(u,v,w,c);add(v,u,,-c);}
#define inf 0x7fffffff
int q[maxn],h,t; int dis[maxn];bool mark[maxn];
bool spfa()
{
memset(mark,,sizeof(mark));
for (int i=S; i<=T; i++) dis[i]=inf;
h=,t=;
q[]=T; mark[T]=; dis[T]=;
while (h<t)
{
int now=q[h++]; mark[now]=;
for (int i=head[now]; i; i=edge[i].next)
if (edge[i^].cap && dis[now]+edge[i^].cost<dis[edge[i].to])
{
dis[edge[i].to]=dis[now]+edge[i^].cost;
if (!mark[edge[i].to])
mark[edge[i].to]=,q[t++]=edge[i].to;
}
}
return dis[S]!=inf;
}
int dfs(int loc,int low)
{
mark[loc]=;
if (loc==T) return low;
int w,used=;
for (int i=head[loc]; i; i=edge[i].next)
if (!mark[edge[i].to] && edge[i].cap && dis[edge[i].to]==dis[loc]-edge[i].cost)
{
w=dfs(edge[i].to,min(low-used,edge[i].cap));
edge[i].cap-=w; edge[i^].cap+=w;
ans+=w*edge[i].cost; used+=w;
if (used==low) return low;
}
return used;
}
int zkw()
{
int tmp=;
while (spfa())
{
mark[T]=;
while (mark[T])
{
memset(mark,,sizeof(mark));
tmp+=dfs(S,inf);
}
}
return tmp;
}
int power(int x){return x*x;}
void build()
{
S=,T=n+m+;
for(int a,b,i=; i<=m; i++)
insert(S,i,,),
a=read(),b=read(),
insert(i,a+m,,),insert(i,b+m,,),
num[a]++,num[b]++;
for(int i=; i<=n; i++)
team[i].lose+=num[i];
for(int i=; i<=n; i++)
ans+=power(team[i].win)*team[i].C+power(team[i].lose)*team[i].D;
for(int i=; i<=n; i++)
for(int j=;j<=num[i];j++)
insert(i+m,T,,*team[i].C*team[i].win+team[i].C+team[i].D-*team[i].D*team[i].lose),
team[i].lose--,team[i].win++;
}
int main()
{
n=read(),m=read();
for (int i=; i<=n; i++)
team[i].win=read(),team[i].lose=read(),
team[i].C=read(),team[i].D=read();
build();
int Maxflow=zkw();
printf("%d\n",ans);
return ;
}
吐槽一句..增广的过程中,一开始使用STL中的queue然后莫名的WA了?手写了个q...怒A...跑得飞快
【BZOJ-1449&2895】球队收益&球队预算 最小费用最大流的更多相关文章
- BZOJ1449[JSOI2009]球队收益&BZOJ2895球队预算——最小费用最大流
题目描述 输入 输出 一个整数表示联盟里所有球队收益之和的最小值. 样例输入 3 3 1 0 2 1 1 1 10 1 0 1 3 3 1 2 2 3 3 1 样例输出 43 提示 要求总费用最低 ...
- 【BZOJ】1221: [HNOI2001] 软件开发(最小费用最大流)
http://www.lydsy.com/JudgeOnline/problem.php?id=1221 先吐槽一下,数组依旧开小了RE:在spfa中用了memset和<queue>的版本 ...
- BZOJ 1877:[SDOI2009]晨跑(最小费用最大流)
晨跑DescriptionElaxia最近迷恋上了空手道,他为自己设定了一套健身计划,比如俯卧撑.仰卧起坐等 等,不过到目前为止,他坚持下来的只有晨跑. 现在给出一张学校附近的地图,这张地图中包含N个 ...
- 【BZOJ1449/2895】[JSOI2009]球队收益/球队预算 最小费用最大流
[BZOJ2895]球队预算 Description 在一个篮球联赛里,有n支球队,球队的支出是和他们的胜负场次有关系的,具体来说,第i支球队的赛季总支出是Ci*x^2+Di*y^2,Di<=C ...
- bzoj 4842 [Neerc2016]Delight for a Cat 最小费用最大流,线性规划
题意:有n个小时,对于第i个小时,睡觉的愉悦值为si,打隔膜的愉悦值为ei,同时对于任意一段连续的k小时,必须至少有t1时间在睡觉,t2时间在打隔膜.如果要获得的愉悦值尽 量大,求最大的愉悦值和睡觉还 ...
- BZOJ 1834 Luogu P2604 [ZJOI2010]网络扩容 (最小费用最大流)
题目连接: (luogu) https://www.luogu.org/problemnew/show/P2604 (bzoj) https://www.lydsy.com/JudgeOnline/p ...
- 【BZOJ】1877: [SDOI2009]晨跑(最小费用最大流)
http://www.lydsy.com/JudgeOnline/problem.php?id=1877 费用流做多了,此题就是一眼题. 拆点表示只能经过一次,容量为1,费用为0. 然后再连边即可,跑 ...
- bzoj 4819: [Sdoi2017]新生舞会【二分+最小费用最大流】
如果\( b[i]==0 \)那么就是裸的费用流/KM,当然KM快一些但是为什么不写KM呢因为我不会打板子了 考虑二分答案,那么问题变成了判定问题. \[ ans=\frac {a_1+a_2+... ...
- 洛谷 P4307 [JSOI2009]球队收益 / 球队预算(最小费用最大流)
题面 luogu 题解 最小费用最大流 先假设剩下\(m\)场比赛,双方全输. 考虑\(i\)赢一局的贡献 \(C_i*(a_i+1)^2+D_i*(b_i-1)^2-C_i*a_i^2-D_i*b_ ...
随机推荐
- GetComponent
GetComponent 的几种写法: 1.AutoRotation cmp1=(AutoRotation) GetComponent(typeof(AutoRotation)); 2.AutoRot ...
- NVIDIA Physix Unity3D
提升机器的3D性能 在公司用的台式机看配置不会很差,但是在处理3D方面特别地无奈!例如开个PS,3d MAX就会卡的半死,再多开一会儿就直接未响应,然后机器重启. 真无奈啊,公司暂时也不会给我换电脑或 ...
- JMeter学习(三十二)属性和变量
一.Jmeter中的属性: 1.JMeter属性统一定义在jmeter.properties文件中,我们可以在该文件中添加自定义的属性 2.JMeter属性在测试脚本的任何地方都是可见的(全局),通常 ...
- Linux命令学习-mpstat
mpstat 用于获取多个 CPU 相关统计信息的有用的命令是 mpstat.下面是一个示例输出: # mpstat -P ALL 5 2 Linux 2.6.9-67.ELsmp (oraclera ...
- java 21 - 3 字符输入流
所谓的输入流,就是读取文件中的数据 同样的,字符输入流InputStreamReader 4个构造方法,不过2个比较常用: 构造方法: A:InputStreamReader(InputStream ...
- C和指针笔记 3.8 static关键字
当用于不同的上下文环境时,static关键字具有不同的意思. 当它用于函数定义时,或用于代码块之外的变量声明时,static关键字用于修改标识符的链接属性,从external改为internal,但标 ...
- js轮询
业务场景为5秒ajax方式请求服务端更新状态,setInterval带参数模式. var objTimer = null; //创建 objTimer=setInterval(function(){l ...
- [转]在Ubuntu 下安装Redis 并使用init 脚本启动
1. 下载安装: cd /tmp wget http://redis.googlecode.com/files/redis-2.2.4.tar.gz tar -zxf redis-2.2.4.ta ...
- Discuz! X的CSS加载机制
首先,每个页面都会加载以下两个css,data/cache/style_1_common.css和data/cache/style_1_forum_index.css.先讲讲这两个文件名的命名规则:第 ...
- WebAPI使用多个xml文件生成帮助文档(转)
http://www.cnblogs.com/idoudou/p/xmldocumentation-for-web-api-include-documentation-from-beyond-the- ...