bzoj 1449 [JSOI2009]球队收益(费用拆分,最小费用流)
1449: [JSOI2009]球队收益
Time Limit: 5 Sec Memory Limit: 64 MB
Submit: 547 Solved: 302
[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
【思路】
费用拆分,最小费用最大流。
由S向每场比赛连边(1,0),由每场比赛向两支队伍连边(1,0)。
考虑在胜w场败l场的基础上再赢一场,则增加cost = ci*w^2+di*l^2-ci*(w+1)^2-di*(l+1)^2=2*ci*w+ci+di+2*di*l的收益。当w增加时cost是单调递增的,所以可以每次相应连一条(1,cost)的边然后w++,l--再次添边直到比赛全部胜利,初始时假设剩余比赛全输。
【代码】
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#define FOR(a,b,c) for(int a=(b);a<(c);a++)
using namespace std; typedef long long LL ;
const int maxn = +;
const int INF = 1e9; struct Edge{ int u,v,cap,flow,cost;
};
struct zkw {
int n,m,s,t;
int vis[maxn],d[maxn];
vector<int> G[maxn];
vector<Edge> es; void init(int n) {
this->n=n;
es.clear();
for(int i=;i<n;i++) G[i].clear();
}
void AddEdge(int u,int v,int cap,int cost) {
es.push_back((Edge){u,v,cap,,cost});
es.push_back((Edge){v,u,,,-cost});
m=es.size();
G[u].push_back(m-);
G[v].push_back(m-);
}
bool spfa() {
memset(vis,,sizeof(vis));
for(int i=;i<n;i++) d[i]=INF;
queue<int> q;
d[t]= , vis[t]= , q.push(t);
while(!q.empty()) {
int u=q.front(); q.pop() , vis[u]=;
for(int i=;i<G[u].size();i++) {
Edge& e=es[G[u][i]];
int v=e.v;
if(es[G[u][i]^].cap && d[v]>d[u]-e.cost) {
d[v]=d[u]-e.cost;
if(!vis[v]) {
vis[v]=;
q.push(v);
}
}
}
}
return d[s]!=INF;
}
int dfs(int u,int a,LL& cost) {
vis[u]=; if(u==t) return a;
int used=,w;
for(int i=;i<G[u].size();i++) {
Edge& e=es[G[u][i]];
int v=e.v;
if(d[u]-e.cost==d[v] && !vis[v] && e.cap) {
w=dfs(v,min(a-used,e.cap),cost);
cost+=w*e.cost;
e.cap-=w , es[G[u][i]^].cap+=w;
used+=w; if(used==a) return a;
}
}
return used;
}
int Mincost(int s,int t,LL& cost) {
this->s=s , this->t=t;
int flow=; cost=;
while(spfa()) {
vis[t]=;
while(vis[t]) {
memset(vis,,sizeof(vis));
flow+=dfs(s,INF,cost);
}
}
return flow;
}
} mc; int n,m;
int c[maxn],d[maxn],win[maxn],lose[maxn],in[maxn]; int main() {
scanf("%d%d",&n,&m);
mc.init(n+m+);
int s=n+m,t=s+;
FOR(i,,n)
scanf("%d%d%d%d",&win[i],&lose[i],&c[i],&d[i]);
int u,v;
FOR(i,,m) {
scanf("%d%d",&u,&v);
u--,v--;
in[u]++,in[v]++;
mc.AddEdge(s,i,,);
mc.AddEdge(i,m+u,,);
mc.AddEdge(i,m+v,,);
}
LL ans=;
FOR(i,,n) {
lose[i]+=in[i];
ans+=c[i]*win[i]*win[i]+d[i]*lose[i]*lose[i];
}
FOR(i,,n) {
FOR(j,,in[i]) {
mc.AddEdge(m+i,t,,*c[i]*win[i]+c[i]+d[i]-*d[i]*lose[i]);
lose[i]-- , win[i]++;
}
}
LL cost;
mc.Mincost(s,t,cost);
printf("%lld",cost+ans);
return ;
}
bzoj 1449 [JSOI2009]球队收益(费用拆分,最小费用流)的更多相关文章
- BZOJ 1449 JSOI2009 球队收益 费用流
题目大意:给定nn支球队.第ii支球队已经赢了winiwin_i场.输了loseilose_i场,接下来还有mm场比赛.每一个球队终于的收益为Ci∗x2i+Di∗y2iC_i*x_i^2+D_i*y_ ...
- BZOJ 1449: [JSOI2009]球队收益( 最小费用最大流)
先考虑假如全部输了的收益. 再考虑每场比赛球队赢了所得收益的增加量,用这个来建图.. --------------------------------------------------------- ...
- BZOJ 1449: [JSOI2009]球队收益 最小费用最大流 网络流
https://www.lydsy.com/JudgeOnline/problem.php?id=1449 给每条路加上一个权值,每条路的费用是这条路的流量*权值,求最大流的最小费用. 每次spfa记 ...
- 【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][ ...
- [bzoj 1449] 球队收益(费用流)
[bzoj 1449] 球队收益(费用流) Description Input Output 一个整数表示联盟里所有球队收益之和的最小值. Sample Input 3 3 1 0 2 1 1 1 1 ...
- 【BZOJ1449】[JSOI2009]球队收益(网络流,费用流)
[BZOJ1449][JSOI2009]球队收益(网络流,费用流) 题面 BZOJ 洛谷 题解 首先对于一支队伍而言,总共进行多少场比赛显然是已知的,假设是\(n_i\)场,那么它的贡献是:\(C_i ...
- 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 题解 费用流 由于存在一 ...
随机推荐
- c#正则表达式采集数据
protected void Page_Load(object sender, EventArgs e){ StringBuilder MyStringBuilder = new StringBuil ...
- mysql出现的错误
(一)ERROR 1005 (HY000): Can't create table '.\day19\user_role.frm' (errno: 121) 今天遇到的这个问题是因为创建了五张表,其中 ...
- Xcode 7真机测试详解
1.准备 注意:一定要让你的真机设备的系统版本和app的系统版本想对应,如果不对应就会出现一个很常见的问题:could not find developer disk image 首先,准备好下面的设 ...
- 寻找链表中倒数第K个结点的位置
输入一个链表,输出该链表中倒数第K个结点. struct ListNode { int m_nValue; ListNode* m_pNext; }; ListNode* FindKthToTail( ...
- 【Ural1057】幂和的数量
[题目描述] 写一个程序来计算区间[X,Y]内满足如下条件的整数个数:它恰好等于K个互不相等的B的整数幂之和. 举个例子.令X=15,Y=20,K=2,B=2.在这个例子中,区间[15,20]内有3个 ...
- visualSVN server库迁移(转)
转自:http://blog.csdn.net/yuhuijun_1/article/details/9762683 首先,VisualSVN Server Manager,包含两个路径,一个是安装路 ...
- ubuntu 解压,压缩
.rar解压:rar x FileName.rar压缩:rar a FileName.rar DirName
- Java学习----方法的覆盖
方法的覆盖:子类继承父类,子类重写父类的同名方法. 覆盖的原则: 1. 方法的参数必须跟父类保持一致 2. 子类方法的修饰符的范围必须大于等于父类方法同名的修饰符(public > privat ...
- hold
嘿嘿,很久没写博客了.一懒一拖一浮躁就不行了. 果然烦心事太多,一直懒得编程.结果还是编程才能平复我啊! 明天那什么,别担心,平常心嘛! 还好,看了几部电影,不算没收获.自己有意思就看看电影,别瞎想啥 ...
- YII 创建后台模块
1,在protected/config/main.php目录下修改如下目录 'modules'=>array( // uncomment the following to enable the ...