乙個整數表示聯盟裡所有球隊收益之和的最小值。
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...