bzoj 1449: [JSOI2009]球队收益 (费用流)
来源:互联网 发布:北京java测试薪资 编辑:程序博客网 时间:2024/05/28 05:17
题目描述
传送门
题目大意:在一个篮球联赛里,有n支球队,球队的支出是和他们的胜负场次有关系的,具体来说,第i支球队的赛季总支出是
题解
对于每支队伍,计算出还有打
然后考虑每赢一场的对总支出的影响,
化简后得到
对于每支队伍来说,剩多少场比赛,就从这支队伍代表的点向汇点连几条边,每条边的容量为1,费用为上式的答案,每连完一条边,
每场比赛必有一支队伍获胜,所有源点向每场比赛代表的点连边,容量为1,费用为0
每场比赛向进行的两支队伍连边,容量为1,费用为0.
然后跑费用流即可。
注意最后的答案要加入初值
代码
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<queue>#define N 300010#define inf 1000000000using namespace std;int n,tot,c[N],d[N],cost[N],remain[N],point[N],nxt[N],v[N],ctx[N];int cty[N],du[N],dx[N],dy[N],dis[N],can[N],last[N],ans,m,lost[N],win[N],S,T,cnt[N];void add(int x,int y,int z,int k){ tot++; nxt[tot]=point[x]; point[x]=tot; v[tot]=y; remain[tot]=z; cost[tot]=k; tot++; nxt[tot]=point[y]; point[y]=tot; v[tot]=x; remain[tot]=0; cost[tot]=-k;}int addflow(int s,int t){ int now=t; int ans=inf; while (now!=s) { ans=min(ans,remain[last[now]]); now=v[last[now]^1]; } now=t; while (now!=s){ remain[last[now]]-=ans; remain[last[now]^1]+=ans; now=v[last[now]^1]; } return ans;}bool spfa(int s,int t){ for (int i=1;i<=t;i++) dis[i]=inf,can[i]=0; queue<int> p; p.push(s); dis[s]=0; can[s]=1; while (!p.empty()){ int now=p.front(); p.pop(); for (int i=point[now];i!=-1;i=nxt[i]) if (remain[i]&&dis[v[i]]>dis[now]+cost[i]){ dis[v[i]]=dis[now]+cost[i]; last[v[i]]=i; if(!can[v[i]]) { can[v[i]]=1; p.push(v[i]); } } can[now]=0; } if (dis[t]==inf) return false; int flow=addflow(s,t); ans+=flow*dis[t]; return true;}void solve(int s,int t){ while(spfa(s,t));}int main(){ freopen("a.in","r",stdin);// freopen("my.out","w",stdout); scanf("%d%d",&n,&m); tot=-1; memset(point,-1,sizeof(point)); for (int i=1;i<=n;i++) scanf("%d%d%d%d",&win[i],&lost[i],&c[i],&d[i]); S=n+m+1; T=S+1; for (int i=1;i<=m;i++) { int x,y; scanf("%d%d",&x,&y); add(S,i,1,0); dx[i]=x; dy[i]=y; du[x]++; du[y]++; add(i,x+m,1,0); ctx[i]=tot; add(i,y+m,1,0); cty[i]=tot; } for (int i=1;i<=n;i++) lost[i]+=du[i]; for (int i=1;i<=n;i++) ans+=c[i]*win[i]*win[i]+d[i]*lost[i]*lost[i]; for (int i=1;i<=n;i++) for (int j=1;j<=du[i];j++){ int t=win[i]*2*c[i]+c[i]+d[i]-lost[i]*2*d[i]; add(i+m,T,1,t); win[i]++; lost[i]--; } solve(S,T); printf("%d\n",ans);}
0 0
- BZOJ 1449 JSOI2009 球队收益 费用流
- bzoj 1449: [JSOI2009]球队收益 (费用流)
- [拆边费用流] BZOJ 1449 [JSOI2009]球队收益
- BZOJ 1449: [JSOI2009]球队收益 拆边费用流
- bzoj 1449 [JSOI2009]球队收益(费用拆分,最小费用流)
- 【bzoj1449/2895】 JSOI2009球队收益 费用流
- 【bzoj1449】【JSOI2009】【球队收益】【费用流】
- BZOJ 1449/2895: [JSOI2009]球队收益|网络流
- 1449: [JSOI2009]球队收益
- BZOJ 1449: [JSOI2009]球队收益 此坑必填 先去打cf
- bzoj1449【JSOI2009】球队收益
- 【JSOI2009】bzoj1449 球队收益
- bzoj1449: [JSOI2009]球队收益
- [JSOI2009]球队收益
- BZOJ1449: [JSOI2009]球队收益
- 【BZOJ1449】[JSOI2009]球队收益【最小费用最大流】【单调增函数建图】
- bzoj1149/2895 [JSOI2009]球队收益
- bzoj1449/2895[JSOI2009]球队收益
- unit2.3 系统延迟及定时机制
- ruby淘宝源不能用了
- C++ 操作系统进程中线程同步的四种方式
- ACM题解及各种总结(链接)
- vs2005针对datatable已经有封装好的去重复方法:
- bzoj 1449: [JSOI2009]球队收益 (费用流)
- 利用群体遗传数据估计基因组上重组率
- PAT 1012. 数字分类
- linux学习记录
- for循环之九九乘法表与Scanner
- SVM公式推导
- CAN协议中的PGN
- CSDN日报20170419 ——《我脸上被软件开发刻了几个字》
- code[vs] 1501 二叉树最大宽度和高度