洛谷 P4307 [JSOI2009]球队收益 / 球队预算(最小费用最大流)
题面
题解
最小费用最大流
先假设剩下\(m\)场比赛,双方全输。
考虑\(i\)赢一局的贡献
\(C_i*(a_i+1)^2+D_i*(b_i-1)^2-C_i*a_i^2-D_i*b_i^2\)
\(=C _i+2*a_i*C_i+D_i-2*b_i*D_i\)
建\(m\)个点限制每场比赛只有一个人赢,自\(S\)连一条\((1, 0)\)的边
然后从这\(m\)的点连向和比赛有关的两个点一条\((1, 0)\)的边
考虑关于\(t\)的边
因为\(a_i\)和\(b_i\)会变,不能直接连一条边
然后我们观察一下上面那个式子,
显然,赢得更多,贡献就增长越大
那么,拆边,我们可以对于每个点连向\(t\)很多条边,容量为\(1\),价值是赢了对应场数的贡献
贪心地想,因为赢得更多,贡献增长越大,要最小费用,我们会先走赢得少的边
这样累加答案刚好满足条件呢
Code
#include<bits/stdc++.h>
#define LL long long
#define RG register
using namespace std;
template<class T> inline void read(T &x) {
x = 0; RG char c = getchar(); bool f = 0;
while (c != '-' && (c < '0' || c > '9')) c = getchar(); if (c == '-') c = getchar(), f = 1;
while (c >= '0' && c <= '9') x = x*10+c-48, c = getchar();
x = f ? -x : x;
return ;
}
template<class T> inline void write(T x) {
if (!x) {putchar(48);return ;}
if (x < 0) x = -x, putchar('-');
int len = -1, z[20]; while (x > 0) z[++len] = x%10, x /= 10;
for (RG int i = len; i >= 0; i--) putchar(z[i]+48);return ;
}
const int N = 10000, inf = 2147483647;
struct node {
int to, nxt, w, v;
}g[200*N];
int last[N], gl = 1;
void add(int x, int y, int w, int v) {
g[++gl] = (node) {y, last[x], w, v};
last[x] = gl;
g[++gl] = (node) {x, last[y], 0, -v};
last[y] = gl;
}
queue<int> q;
int pre[N], dis[N], from[N], s, t;
bool vis[N];
bool spfa() {
memset(dis, 127, sizeof(dis));
dis[s] = 0;
q.push(s);
while (!q.empty()) {
int u = q.front(); q.pop();
for (int i = last[u]; i; i = g[i].nxt) {
int v = g[i].to;
if (g[i].w && dis[v] > dis[u] + g[i].v) {
dis[v] = dis[u] + g[i].v; pre[v] = u; from[v] = i;
if (!vis[v]) {
vis[v] = 1;
q.push(v);
}
}
}
vis[u] = 0;
}
return dis[t] != dis[0];
}
int Mcmf() {
int ans = 0;
while (spfa()) {
int di = inf;
for (int i = t; i != s; i = pre[i]) di = min(di, g[from[i]].w);
ans += di*dis[t];
for (int i = t; i != s; i = pre[i]) g[from[i]].w -= di, g[from[i]^1].w += di;
}
return ans;
}
int a[N], b[N], c[N], d[N], cnt[N];
int main() {
int n, m, sum = 0;
read(n), read(m);
s = m+n+1, t = s+1;
for (int i = 1; i <= n; i++)
read(a[i]), read(b[i]), read(c[i]), read(d[i]);
for (int i = 1; i <= m; i++) {
int x, y;
read(x), read(y);
b[x]++, b[y]++;
cnt[x]++; cnt[y]++;
add(s, i, 1, 0);
add(i, x+m, 1, 0);
add(i, y+m, 1, 0);
}
for (int i = 1; i <= n; i++)
sum += c[i]*a[i]*a[i] + d[i]*b[i]*b[i];
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= cnt[i]; j++) {
add(i+m, t, 1, c[i]+2*a[i]*c[i]+d[i]-2*b[i]*d[i]);
b[i]--; a[i]++;
}
}
printf("%d\n", sum+Mcmf());
return 0;
}
洛谷 P4307 [JSOI2009]球队收益 / 球队预算(最小费用最大流)的更多相关文章
- 洛谷 P4009 汽车加油行驶问题 【最小费用最大流】
分层图,建k层,设(i,j,0)为点(i,j)的满油状态,全图的流量都是1,因为重复走到一个点没有意义.如果当前点是加油站,那么它向它上左的点连费用为a的边,向下右连费用为a+b的边: 否则,这个点的 ...
- 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/2895】[JSOI2009]球队收益/球队预算 最小费用最大流
[BZOJ2895]球队预算 Description 在一个篮球联赛里,有n支球队,球队的支出是和他们的胜负场次有关系的,具体来说,第i支球队的赛季总支出是Ci*x^2+Di*y^2,Di<=C ...
- 【BZOJ-1449&2895】球队收益&球队预算 最小费用最大流
1449: [JSOI2009]球队收益 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 648 Solved: 364[Submit][Status][ ...
- 洛谷P4307 球队收益
题意:有n个球队,m场比赛. 每个球队都已经有些胜负场次了. 每个球队的收益为Ci * wini2 - Di * losei2. 求最小可能总收益. 解: 先看出一个模型:用一流量代表一个胜场,每场比 ...
- 【bzoj1449/bzoj2895】[JSOI2009]球队收益/球队预算 费用流
题目描述 输入 输出 一个整数表示联盟里所有球队收益之和的最小值. 样例输入 3 3 1 0 2 1 1 1 10 1 0 1 3 3 1 2 2 3 3 1 样例输出 43 题解 费用流 由于存在一 ...
- 【BZOJ1449】[JSOI2009]球队收益(网络流,费用流)
[BZOJ1449][JSOI2009]球队收益(网络流,费用流) 题面 BZOJ 洛谷 题解 首先对于一支队伍而言,总共进行多少场比赛显然是已知的,假设是\(n_i\)场,那么它的贡献是:\(C_i ...
- 【洛谷2469/BZOJ1927】[SDOI2010]星际竞速(费用流/最小路径覆盖)
题目: 洛谷2469 分析: 把题目翻译成人话:给一个带边权的DAG,求一个路径覆盖方案使路径边权总和最小.从点\(i\)开始的路径需要额外加上\(A_i\)的权值. 回xian忆chang一xue下 ...
- BZOJ 1449: [JSOI2009]球队收益( 最小费用最大流)
先考虑假如全部输了的收益. 再考虑每场比赛球队赢了所得收益的增加量,用这个来建图.. --------------------------------------------------------- ...
随机推荐
- 使用python管理Cisco设备-乾颐堂
今天发现一个老外使用python写的管理cisco设备的小框架tratto,可以用来批量执行命令. 下载后主要有3个文件: Systems.py 定义了一些不同设备的操作系统及其常见命令. Conne ...
- rpm管理
系统上rpm命令管理程序包: 安装.卸载.升级.查询.校验.数据库维护 安装: rpm {-i|--install} [install-options] PACKAGE_FILE ... -v: ve ...
- JS作用域理解(声明提升)
1.JS解析步骤: a.预解析 将变量声明提升: 将函数声明及函数内容提升,可以理解成原来位置的函数在解析代码时已经提到代码初始位置: 块内的变量声明和函数声明也会被提升,例如if语句 遇到重名,只留 ...
- bootstrap缩略图及警示框制作
缩略图在网站中最常用的地方就是产品列表页面,一行显示几张图片,有的在图片底下(左侧或右侧)带有标题.描述等信息.Bootstrap框架将这一部独立成一个模块组件.并通过“thumbnail”样式配合b ...
- 'for' loop initial declarations are only allo
linux系统下的c编程与windows有所不同,如果你在用gcc编译代码的时候提示‘for’ loop initial declarations are only allowed in C99 mo ...
- Cocosd-x-2.2.2 & VS2012 & Eclipse 开发环境搭建
1.安装软件: 1.1 安装JDK(JDK1.7.0_51) JAVA_HOME C:\Program Files\Java\jdk1..0_51 CLASSPATH .;%JAVA_HOME%\li ...
- C# xsd 验证 XML数据有效性 问题
使用XSD进行批量数据导入时生成的XML数据有效性这样的功能已经不是第一次做了,之前做的时候都没有碰到什么问题,这些天在开发中遇到了一个很头痛的问题就是无论XSD文件规则怎么写,验证都是通过的. 下面 ...
- sql分组拼接字段
--联查select n.*,t.Name from News n join Type_News tn on n.Id=tn.NId join Types t on t.Id=tn.TId --拼接并 ...
- springboot pom 详解
Starter POMs是可以包含到应用中的一个方便的依赖关系描述符集合.可以获取所有spring及相关技术的一站式服务,不需要翻阅示例代码,拷贝粘贴大量的依赖描述符. Starter名字的含义: 所 ...
- occal [问题解决]ORA-01427: 单行子查询返回多个行
有人问题我一个问题,情况如下:他要用根据divide_act_channel_day的new_amount字段去更新divide_stat的new_amount字段.两张表关联的条件:day=log_ ...