當前位置:
首頁 >
前端技术
> javascript
>内容正文
javascript
BZOJ1449[JSOI2009]球队收益BZOJ2895球队预算——最小费用最大流
生活随笔
收集整理的這篇文章主要介紹了
BZOJ1449[JSOI2009]球队收益BZOJ2895球队预算——最小费用最大流
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
題目描述
輸入
輸出
一個整數(shù)表示聯(lián)盟里所有球隊收益之和的最小值。樣例輸入
3 31 0 2 1
1 1 10 1
0 1 3 3
1 2
2 3
3 1
樣例輸出
43提示
要求總費用最低考慮最小費用最大流。對于一場比賽同時決策兩支隊伍誰輸誰贏不好辦,我們先假設剩下的比賽每支隊伍都輸了,這樣每次只要決策誰贏了即可。對于每次比賽將源點連向比賽,流量為$1$、費用為$0$;再將比賽連向兩支隊伍,流量為$1$、費用為$0$。假設每支隊伍還有$k[i]$場比賽,那么就將這只隊伍向匯點連$k[i]$條邊,流量為$1$,每條邊費用為多贏一次的收益。每支隊伍的起始收益為$C[i]*x^2+D[i]*y^2,x=win[i],y=lose[i]+k[i]$,每多贏一次的收益為$C*(x+1)^2+D*(y-1)^2-C*x^2-D*y^2=C*(2x+1)-D*(2y-1)$,因為$D\le C$,所以每多贏一次的收益會單調遞增,又因為是最小費用最大流,所以一定先選贏一次的邊、再選贏兩次的邊、再選贏三次的邊…… #include<set> #include<map> #include<queue> #include<stack> #include<cmath> #include<cstdio> #include<vector> #include<bitset> #include<cstring> #include<iostream> #include<algorithm> #define ll long long #define INF 10000000 using namespace std; int head[10000]; int next[20000]; int to[20000]; int v[20000]; int c[20000]; int f[10000]; int from[20000]; int tot=1; int S,T; ll ans; int n,m; int x,y; int s[10000]; int win[10000]; int lose[10000]; int C[10000]; int D[10000]; queue<int>q; int vis[10000]; int d[10000]; void add(int x,int y,int z,int w) {next[++tot]=head[x];head[x]=tot;to[tot]=y;v[tot]=z;c[tot]=w;from[tot]=x;next[++tot]=head[y];head[y]=tot;to[tot]=x;v[tot]=-z;c[tot]=0;from[tot]=y; } void result() {int now=T;int flow=INF;while(now!=S){flow=min(flow,c[f[now]]);now=from[f[now]];}ans+=1ll*d[T]*flow;now=T;while(now!=S){c[f[now]]-=flow;c[f[now]^1]+=flow;now=from[f[now]];} } bool SPFA() {for(int i=1;i<=T;i++){d[i]=INF;}d[S]=0;q.push(S);vis[S]=1;while(!q.empty()){int now=q.front();q.pop();vis[now]=0;for(int i=head[now];i;i=next[i]){if(!c[i]){continue;}if(d[to[i]]>d[now]+v[i]){d[to[i]]=d[now]+v[i];f[to[i]]=i;if(!vis[to[i]]){q.push(to[i]);vis[to[i]]=1;}}}}return d[T]!=INF; } void find_min() {while(SPFA()){result();} } int main() {scanf("%d%d",&n,&m);S=n+m+1;T=S+1;for(int i=1;i<=n;i++){scanf("%d%d%d%d",&win[i],&lose[i],&C[i],&D[i]);}for(int i=1;i<=m;i++){add(S,n+i,0,1);scanf("%d%d",&x,&y);s[x]++,s[y]++;add(n+i,x,0,1);add(n+i,y,0,1);}for(int i=1;i<=n;i++){ans+=1ll*C[i]*win[i]*win[i]+1ll*D[i]*(lose[i]+s[i])*(lose[i]+s[i]);x=win[i],y=lose[i]+s[i];for(int j=1;j<=s[i];j++){add(i,T,C[i]*(2*x+1)-D[i]*(2*y-1),1);x++,y--;}}find_min();printf("%lld",ans); }轉載于:https://www.cnblogs.com/Khada-Jhin/p/10569488.html
總結
以上是生活随笔為你收集整理的BZOJ1449[JSOI2009]球队收益BZOJ2895球队预算——最小费用最大流的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: go不使用工具包将大写字符转成小写字符的
- 下一篇: 4.线程