JSOI2009 bzoj1449 球隊收益

2021-07-27 08:28:17 字數 1284 閱讀 5631

description input output 乙個整數表示聯盟裡所有球隊收益之和的最小值。

首先假設全輸,然後給每場比賽分配乙個贏家,每個隊伍每多贏一場多獲得的收益作為費用。

但是有乙個問題,如何保證每次走的是對應的邊?也就是,如何保證贏第一場的時候增加的收益是贏一場減贏零場,而不是贏兩場減贏一場?可以發現,假設當前贏了

x 場輸了

y場,多贏一場的收益是2c

ix−2

diy+

ci+d

i ,

x 越大,

y越小,上式越大。因此每次一定優先走

x 比較小的邊。

#include

#include

#include

using namespace std;

const int

s=6005,t=6006,oo=0x3f3f3f3f,mod=6007;

int fir[6010],ne[200010],to[200010],w[200010],c[200010],

que[6010],in[6010],minw[6010],len[6010],fa[6010],

cnt[5010],ci[5010],di[5010],win[5010],lose[5010],

n,m,num,ans;

void add(int u,int v,int

x,int

y)int main()

for (int i=1;i<=n;i++)

for (int j=1;j<=cnt[i];j++)

add(i,t,1,ci[i]*(win[i]+j)*(win[i]+j)+di[i]*(lose[i]+cnt[i]-j)*(lose[i]+cnt[i]-j)

-ci[i]*(win[i]+j-1)*(win[i]+j-1)-di[i]*(lose[i]+cnt[i]-j+1)*(lose[i]+cnt[i]-j+1));

for (int i=1;i<=n;i++) ans+=ci[i]*win[i]*win[i]+di[i]*(lose[i]+cnt[i])*(lose[i]+cnt[i]);

while (1)

}in[u]=0;

}if (!minw[t]) break;

ans+=minw[t]*len[t];

for (int i=fa[t];i;i=fa[to[i^1]])

}printf("%d\n",ans);

}

bzoj1449 JSOI2009 球隊收益

傳送門 感覺就是費用流呀。可以發現這道題與之前的費用流題有所不同,因為乙個球隊不論輸還是贏都會獲得收益。這裡就要用到乙個技巧,我們可以假裝比賽雙方都輸,然後修改贏的就ok辣。然後就是每個人向終點連邊,這裡的費用隨著流量的變化而變化,所以我們要用到拆邊法。考慮乙個人從贏win i 次 輸lose i ...

BZOJ1449 JSOI2009 球隊收益

bzoj luogu 在乙個籃球聯賽裡,有 n 支球隊,球隊的支出是和他們的勝負場次有關係的,具體來說,第i支球隊的賽季總支出是 c i times x 2 d i times y 2,d i le c i 其中 x,y 分別表示這只球隊本賽季的勝負場次。現在賽季進行到了一半,每只球隊分別取得了 a...

bzoj1449 JSOI2009 球隊收益

time limit 5 sec memory limit 64 mb submit 1131 solved 640 submit status discuss 乙個整數表示聯盟裡所有球隊收益之和的最小值。3 31 0 2 1 1 1 10 1 0 1 3 3 1 22 3 3 143 分析 很妙的...