BZOJ1449 JSOI2009 球隊收益

2022-05-20 04:52:21 字數 2042 閱讀 8161

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

3 31 0 2 1

1 1 10 1

0 1 3 3

1 22 3

3 143

這題挺逗的。。。很好看出來是網路流

難點就在於你不能在跑網路流的時候把輸贏的利益一起算上

所以做法很光(you)棍(xiu):每場比賽每隊都算輸,然後看看是哪個贏

根據它給的公式可以拆開,對於每乙個球隊,就建出每多贏一場的利益

它說明了它ci>=di,所以這肯定是遞增的,就可以直接跑最小費用最大流了

**如下:

//

mt_li

#include#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define ll long long

#define mp(x,y) make_pair(x,y)

#define pll pair#define pii pairusing

namespace

std;

inline

intread()

while(ch>='

0'&&ch<='9')

return x*f;

}int stack[20

];inline

void write(int

x)

if(!x)

int top=0

;

while(x)stack[++top]=x%10,x/=10

;

while(top)putchar(stack[top--]+'0'

);}inline

void pr1(int x)

inline

void pr2(int x)

struct

nodea[

21000];int len,last[11000

];void ins(int x,int y,int c,int

d);last[x]=len;

a[++len]=(node);last[y]=len;

}int lose[5100],win[5100],c[5100],d[5100

];int

n,m,st,ed;

int head,tail,list[110000

];int d[11000

],ans;

int cc[11000],pre[11000

];bool v[11000

];bool

spfa()}}

head++;

v[x]=false

; }

if(d[ed]==9999999)return

false

; ans+=d[ed]*cc[ed];

int x=ed;

while(x!=0

)

return

true;}

int match[5100

];int

main()

for(int i=1;i<=n;i++)lose[i]+=match[i];

int sum=0

;

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

sum+=win[i]*win[i]*c[i]+lose[i]*lose[i]*d[i];

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

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

ans=0

;

while

(spfa());

printf(

"%d\n

",sum+ans);

return0;

}

JSOI2009 bzoj1449 球隊收益

description input output 乙個整數表示聯盟裡所有球隊收益之和的最小值。首先假設全輸,然後給每場比賽分配乙個贏家,每個隊伍每多贏一場多獲得的收益作為費用。但是有乙個問題,如何保證每次走的是對應的邊?也就是,如何保證贏第一場的時候增加的收益是贏一場減贏零場,而不是贏兩場減贏一場?...

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...