[bzoj 1449] 球队收益(费用流)
[bzoj 1449] 球队收益(费用流)
Description

Input

Output
一个整数表示联盟里所有球队收益之和的最小值。
Sample Input
3 3
1 0 2 1
1 1 10 1
0 1 3 3
1 2
2 3
3 1
Sample Output
43
Hint

Solution
这题费用流裸题好吧。
先假设所有队在接下来的比赛中都会输掉,算出收益。
但是一场比赛应该有且只有一支球队赢得比赛,所以真实收益和我们算出来的收益就会有一些差值,再计算最小的差值即可。
我们可以发现,队伍\(i\)每赢得一场比赛,就会多获得\(C_i * (2 * Win_i + 1) - D_i * (2 * Lost_i - 1)\) 的收益,并且由于赢得越多,\(Win_i\)就会越大,\(Lost_i\)就会越小,所以获得的收益差值就会越来越大。 于是我们可以建立一个最小费用最大流的模型。
- 我们建立一个源点,向所有比赛建一条流量为1,费用为0的边。
- 从比赛向其两支球队建立一条流量为1,费用为0的边。
- 从每支球队向汇点建x(x是该支球队参加的比赛数)条边,每条边流量为1,费用每赢一场的差值。
PS: 这里要注意一点,差值会随着赢的场数增多而增多,所以最小费用最大流一定会先走赢第一场,再走第二场,第三场,等等。。。这是算法正确性的关键。
建好图,然后跑一遍最小费用最大流,加上之前的答案,这题就完了。
Code
#include <cstdio>
#include <queue>
#include <iostream>
using namespace std;
const int maxn = 5e3 + 10, maxm = 1e3 + 10, inf = 1e9 + 7;
int n, m, S, T, cnt;
int w[maxn], l[maxn], a[maxn], b[maxn], x[maxn];
int dis[maxn+maxm], inq[maxn+maxm];
queue<int> q;
struct edge {int u, v, f, c; edge *next, *rev;} e[maxn<<1], *head[maxn+maxm], *from[maxn+maxm];
inline void adde(int u, int v, int flow, int cost) {
e[cnt] = (edge){u, v, flow, cost, head[u], &e[cnt+1]}, head[u] = &e[cnt++];
e[cnt] = (edge){v, u, 0, -cost, head[v], &e[cnt-1]}, head[v] = &e[cnt++];
}
bool spfa() {
while(!q.empty()) q.pop();
for(int i = 1; i <= m + n + 1; i++) dis[i] = inf, inq[i] = 0, from[i] = NULL;
dis[S] = 0, inq[S] = 1; q.push(S);
while(!q.empty()) {
int u = q.front(); q.pop(), inq[u] = 0;
for(edge *k = head[u]; k; k = k->next) if(k->f) {
if(dis[k->v] > dis[u] + k->c) {
dis[k->v] = dis[u] + k->c;
from[k->v] = k;
if(!inq[k->v]) inq[k->v] = 1, q.push(k->v);
}
}
}
return dis[T] != inf;
}
int mcf() {
int res = 0, xx = inf;
for(edge *k = from[T]; k; k = from[k->u]) xx = min(xx, k->f);
for(edge *k = from[T]; k; k = from[k->u])
res += xx * k->c, k->f -= xx, k->rev->f += xx;
return res;
}
int main() {
int u, v;
scanf("%d%d", &n, &m);S = 0, T = n + m + 1;
for(int i = 1; i <= n; i++) scanf("%d%d%d%d", w+i, l+i, a+i, b+i);
for(int i = 1; i <= m; i++) {
scanf("%d%d", &u, &v);
l[u]++, l[v]++;
x[u]++, x[v]++;
adde(S, n+i, 1, 0);
adde(n + i, u, 1, 0);
adde(n + i, v, 1, 0);
}
int ans = 0;
for(int i = 1; i <= n; i++) {
ans += w[i] * w[i] * a[i] + l[i] * l[i] * b[i];
for(int j = 0; j < x[i]; j++)
adde(i, T, 1, a[i]*(2*w[i]+1) - b[i] * (2 * l[i] - 1)),
w[i]++, l[i]--;
}
while(spfa()) ans += mcf();
printf("%d\n", ans);
return 0;
}
[bzoj 1449] 球队收益(费用流)的更多相关文章
- BZOJ 1449 JSOI2009 球队收益 费用流
题目大意:给定nn支球队.第ii支球队已经赢了winiwin_i场.输了loseilose_i场,接下来还有mm场比赛.每一个球队终于的收益为Ci∗x2i+Di∗y2iC_i*x_i^2+D_i*y_ ...
- BZOJ 1449 球队收益(最小费用最大流)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1449 题意: 思路:首先,我们假设后面的M场比赛两方都是输的,即初始时的lose[i]再 ...
- 【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&&2895】球队预算 [费用流]
球队预算 Time Limit: 10 Sec Memory Limit: 256 MB[Submit][Status][Discuss] Description 在一个篮球联赛里,有n支球队, 球 ...
- BZOJ.2597.[WC2007]剪刀石头布(费用流zkw)
BZOJ 洛谷 \(Description\) 给定一张部分边方向已确定的竞赛图.你需要给剩下的边确定方向,使得图中的三元环数量最多. \(n\leq100\). \(Solution\) 这种选择之 ...
- bzoj 1070: [SCOI2007]修车 费用流
1070: [SCOI2007]修车 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 2785 Solved: 1110[Submit][Status] ...
- BZOJ 3171 循环格(费用流)
题意 一个循环格就是一个矩阵,其中所有元素为箭头,指向相邻四个格子.每个元素有一个坐标(行,列),其中左上角元素坐标为(0,0).给定一个起始位置(r,c),你可以沿着箭头防线在格子间行走.即如果(r ...
- BZOJ 1070 修车 【费用流】
Description 同一时刻有N位车主带着他们的爱车来到了汽车维修中心.维修中心共有M位技术人员,不同的技术人员对不同 的车进行维修所用的时间是不同的.现在需要安排这M位技术人员所维修的车及顺序, ...
- BZOJ 1930 吃豆豆(费用流)
首先这题的两条线不相交的限制可以去掉,因为如果相交的话把点换一换是不影响最终结果的. 剩下的费用流建图是显然的,把点拆为两个,建立超级源点s和源点ss汇点t,连边(s,ss,2,0). 对于每个点,连 ...
随机推荐
- Java 添加播放MIDI音乐
Java 在多媒体处理方面的确优势不大,但是我们在程序中有些时候又需要一些音乐. 如果播放的音乐是wav等波形音频文件,又很大的话,所以背景音乐最好就是MIDI了. 网上很多播放MIDI的教程都是 ...
- [Machine Learning with Python] Familiar with Your Data
Here I list some useful functions in Python to get familiar with your data. As an example, we load a ...
- 快速比较两个uiimage是否相等防止使用原始dsdata造成界面卡顿问题
UIImage *imageLater = image1; UIImage *imagePre = image2; if (imageLater == imagePre){....}
- 【Exception】查看异常出现在具体的文件名/类名/方法名/具体行号
今天在处理异常日志保存过程中,想要获取到异常抛出在具体在那个文件,哪个类下的哪个方法中的具体第几行,所以具体实现如下 try{ Integer adminID = Integer.parseInt(a ...
- 利用泛型和反射,管理配置文件,把Model转换成数据行,并把数据行转换成Model
利用泛型和反射,管理配置文件,把Model转换成数据行,并把数据行转换成Model 使用场景:网站配置项目,为了便于管理,网站有几个Model类来管理配置文件, 比如ConfigWebsiteMo ...
- 图像处理算法2——Otsu最佳阈值分割法http://blog.csdn.net/xiaqunfeng123/article/details/17121195
http://blog.csdn.net/xiaqunfeng123/article/details/17121195Otsu法是1979年由日本大津提出的.该方法在类间方差最大的情况下是最佳的,即统 ...
- 手把手教你nginx/linux下如何增加网站
先进入到nginx的配置文件目录请输入以下命令 cd /alidata/server/nginx/conf/vhosts 再输入 ll 看看是不是像下面截图的一样 用神器xftp将default. ...
- Android 非静态内部类导致内存泄漏原因深入剖析
背景 上周发现蘑菇街IM-Android代码里面.一些地方代码编写不当.存在内存泄漏的问题.在和疯紫交流的过程中.发现加深了一些理解,所以决定写一下分析思路,相互学习. 内存泄漏 一个不会被使用的对象 ...
- Swift中的switch 和 do while
switch后面的()能够省略 OC中的switch假设没有break就会穿透(依次运行),在Swift中不会穿透(可理解默认就有break) OC中入股要在case中定义变量,必要要加上{}确定作用 ...
- cocos2dx3.2 学习笔记(2)--ActionManagerTest
前面看完了 CppTests的基本框架及流程.如今准备看看详细的每一个Test了 从哪里開始看呢. 额,就第一个吧(ActionManagerTest) 首先看看效果吧,执行了下.发现有几种效果.看不 ...