BZOJ1449 球隊收益

2022-05-20 08:42:17 字數 1339 閱讀 9671

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

3 31 0 2 1

1 1 10 1

0 1 3 3

1 22 3

3 1我們先假設所有的球隊都贏,算出答案。然後每場比賽都要提供乙個輸的場次。

考慮費用流。源點向每場比賽連邊,每場比賽向兩隻隊伍連邊,隊伍再向匯點連邊。

注意到乙隻隊伍的得分是關於輸的場次的乙個二次函式,所以每增加乙個輸場,增加或減少的收益不一樣。所以我們拆邊。設\(f_\)表示第\(i\)只隊伍輸\(k\)場的收益,則第\(a\)條邊的權值為\(f_-f_\)。然後再跑最小費用流。

因為這是個開口向上的二次函式,它的二階導是大於\(0\)的。 所以\(f_-f_\)單調遞增,這麼拆邊是對的。

**:

#include#define ll long long

#define n 15005

using namespace std;

inline int get() while('0'<=ch&&ch<='9') return x*f;}

int n,m;

int s,t;

int win[n],lose[n];

int c[n],d[n];

int a[n],b[n];

struct road s[n<<4];

int h[n<<2],cnt=1;

void add(int i,int j,int f,int c) ;h[i]=cnt;

s[++cnt]=(road) ;h[j]=cnt;

}int tim[n];

ll ans;

ll dis[n];

queueq;

int fr[n],e[n];

bool in[n];

bool spfa(int s)

}} }

if(dis[t]>1e9) return 0;

ans+=dis[t];

for(int i=t;i;i=fr[i])

return 1;

}int main()

t=m+n+1;

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

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

} while(spfa(s));

cout<

return 0;

}

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