[JSOI2009]球队收益
这题好神啊
我们发现一个球队的总比赛场数是确定的,设第\(i\)支球队一共进行了\(s_i\)场比赛
于是这个球队的收益就是\(c_i\times x^2+d_i(s_i-x)^2\)
我们拆开柿子可以发现\(c_ix^2+d_ix^2+d_is_i^2-2xs_id_i\)
我们拿出和\(x\)有关的项来发现\((c_i+d_i)x^2-2s_id_ix\)
现在我们把贡献变成只和胜场数\(x\)有关了,考虑\(x+1\)的时候这个柿子的增量,我们发现是\((2x+1)(c_i+d_i)-2s_id_i\),我们发现这个增量是单增的
于是我们现在可以这样建图
对于每一场比赛我们建一个点,源点向这个点连一条流量为\(1\)费用为\(0\)的边
这个点向对应的两支球队也连一条流量为\(1\)费用为\(0\)的边
对应的两支球队向汇点连流量为\(1\)费用为对应增量的边,同时我们让这两支球队的胜场数的加\(1\)
由于增量是单增的,我们跑的是一个最小费用流,所以肯定会优先选择那些费用较小的也就是对应的胜场数较少的边了
最后的答案就是费用流跑出来的答案加上初始的贡献
代码
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define re register
#define LL long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
inline int read() {
	char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();
	while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
}
std::queue<int> q;
const int inf=999999999;
const int maxn=6005;
struct E{int v,nxt,w,f;}e[maxn*10];
int n,m,num=1,S,T;
int head[maxn],vis[maxn],dis[maxn];
int a[maxn],b[maxn],s[maxn],c[maxn],d[maxn],x[maxn],y[maxn];
inline void C(int x,int y,int f,int w) {e[++num].v=y;e[num].nxt=head[x];head[x]=num;e[num].w=w;e[num].f=f;}
inline void add(int x,int y,int f,int w) {C(x,y,f,w),C(y,x,0,-1*w);}
inline int SPFA() {
	for(re int i=S;i<=T;i++) dis[i]=inf,vis[i]=0;
	dis[T]=0,q.push(T);
	while(!q.empty()) {
		int k=q.front();q.pop();vis[k]=0;
		for(re int i=head[k];i;i=e[i].nxt)
		if(e[i^1].f&&dis[e[i].v]>dis[k]+e[i^1].w) {
			dis[e[i].v]=dis[k]+e[i^1].w;
			if(!vis[e[i].v]) vis[e[i].v]=1,q.push(e[i].v);
		}
	}
	return dis[S]<inf;
}
int dfs(int x,int now) {
	if(x==T||!now) return now;
	int flow=0,ff;vis[x]=1;
	for(re int i=head[x];i;i=e[i].nxt)
	if(!vis[e[i].v]&&e[i].f&&dis[e[i].v]==dis[x]+e[i^1].w) {
		ff=dfs(e[i].v,min(e[i].f,now));
		if(ff<=0) continue;
		now-=ff,flow+=ff,e[i].f-=ff,e[i^1].f+=ff;
		if(!now) break;
	}
	return flow;
}
inline int zkw() {
	int ans=0;
	while(SPFA()) {
		vis[T]=1;
		while(vis[T]) {
			for(re int i=S;i<=T;i++) vis[i]=0;
			ans+=dfs(S,inf)*dis[S];
		}
	}
	return ans;
}
int main() {
	n=read(),m=read();
	for(re int i=1;i<=n;i++) a[i]=read(),b[i]=read(),c[i]=read(),d[i]=read();
	for(re int i=1;i<=m;i++) x[i]=read(),y[i]=read(),s[x[i]]++,s[y[i]]++;
	for(re int i=1;i<=n;i++) s[i]+=a[i]+b[i];
	int ans=0;T=n+m+1;
	for(re int i=1;i<=n;i++) ans+=c[i]*a[i]*a[i]+d[i]*(s[i]-a[i])*(s[i]-a[i]);
	for(re int i=1;i<=m;i++) {
		add(S,n+i,1,0),add(n+i,x[i],1,0),add(n+i,y[i],1,0);
		add(x[i],T,1,(2*a[x[i]]+1)*(c[x[i]]+d[x[i]])-2*d[x[i]]*s[x[i]]);
		add(y[i],T,1,(2*a[y[i]]+1)*(c[y[i]]+d[y[i]])-2*d[y[i]]*s[y[i]]);
		a[x[i]]++,a[y[i]]++;
	}
	printf("%d\n",ans+zkw());
	return 0;
}
[JSOI2009]球队收益的更多相关文章
- bzoj 1449 [JSOI2009]球队收益(费用拆分,最小费用流)
		1449: [JSOI2009]球队收益 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 547 Solved: 302[Submit][Status][ ... 
- BZOJ 1449: [JSOI2009]球队收益( 最小费用最大流)
		先考虑假如全部输了的收益. 再考虑每场比赛球队赢了所得收益的增加量,用这个来建图.. --------------------------------------------------------- ... 
- 【BZOJ1449】[JSOI2009]球队收益(网络流,费用流)
		[BZOJ1449][JSOI2009]球队收益(网络流,费用流) 题面 BZOJ 洛谷 题解 首先对于一支队伍而言,总共进行多少场比赛显然是已知的,假设是\(n_i\)场,那么它的贡献是:\(C_i ... 
- 【BZOJ 1449】 1449: [JSOI2009]球队收益 (最小费用流)
		1449: [JSOI2009]球队收益 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 841 Solved: 483 Description Inpu ... 
- 1449: [JSOI2009]球队收益
		1449: [JSOI2009]球队收益 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 757 Solved: 437[Submit][Status][ ... 
- Bzoj1449 [JSOI2009]球队收益
		Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 741 Solved: 423 Description Input Output 一个整数表示联盟里所有球 ... 
- BZOJ1449[JSOI2009]球队收益&BZOJ2895球队预算——最小费用最大流
		题目描述 输入 输出 一个整数表示联盟里所有球队收益之和的最小值. 样例输入 3 3 1 0 2 1 1 1 10 1 0 1 3 3 1 2 2 3 3 1 样例输出 43 提示 要求总费用最低 ... 
- 【bzoj1449/bzoj2895】[JSOI2009]球队收益/球队预算  费用流
		题目描述 输入 输出 一个整数表示联盟里所有球队收益之和的最小值. 样例输入 3 3 1 0 2 1 1 1 10 1 0 1 3 3 1 2 2 3 3 1 样例输出 43 题解 费用流 由于存在一 ... 
- BZOJ 1449 JSOI2009 球队收益 费用流
		题目大意:给定nn支球队.第ii支球队已经赢了winiwin_i场.输了loseilose_i场,接下来还有mm场比赛.每一个球队终于的收益为Ci∗x2i+Di∗y2iC_i*x_i^2+D_i*y_ ... 
随机推荐
- C#获取gif帧数
			C#获取gif帧数 /// <summary> /// 获取gif帧数 /// </summary> /// <param name="gifBytes&quo ... 
- winform窗体   小程序【移动窗体和阴影】
			窗体无边框设置后无法移动,引用API 使其获得功能 移动 //窗体移动API [DllImport("user32.dll")] public static extern bool ... 
- 关于eclipse的项目前有感叹号和errors exist in required project相关问题
			一般来说 项目运行中 各个类的信息中并没有报错 但在运行中会出现errors exist in required project 且有时候运行也会成功.这种情况是由于项目中其他的类存在问题未解决 导 ... 
- 【mysql】连接的空闲时间超过8小时后 MySQL自动断开该连接解决方案
			1. 增加 MySQL 的 wait_timeout 属性的值. 修改 /etc/mysql/my.cnf文件,在 [mysqld] 节中设置: # Set a connection to wait ... 
- Another kind of Fibonacci(矩阵)
			Another kind of Fibonacci Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Jav ... 
- 【C#数据结构系列】线性表
			一:线性表 1.1:定义:零个或多个数据元素的有限序列 1.2: 线性表元素个数n定义为线性表的长度,n = 0称为空表,i 为数据元素ai在线性表中的位序. 1.3:满足线性表的条件:(1):有序, ... 
- 微信公众号获取acess_token并存储(php)
			<?php define("appid", "你的appid"); define("appsecret", "你的appse ... 
- 华为5G折叠屏幕适配
			华为5G折叠屏幕的发布,迎来新的一个设备——移动端的折叠设备华为Max;华为Max设备分辨率有以下几种 8.0,6.8,6.38,这三种场景下页面展示都是不一样的表现,需要我们在开发中注意监听屏幕变化 ... 
- Oracle查询时15分钟划分
			select to_date(to_char(sysdate, 'yyyy-MM-dd hh24') || ':' || floor(to_number(to_char(s ... 
- iOS 开发之环形倒计时进度条(虚线/实线)
			代码很简单,一看便知.这里为顺时针,若想要逆时针,clockwise改为0,还需更改起始角度和终点角度. 源码地址:https://github.com/LfyDragon/CountDown 直接上 ... 
