這是一道凸費用的題,需要用到拆邊的轉化。
具體是這樣,首先列出關於流量xi的費用式子:f(xi)=ci*xi2+di*(si-xi)2=(ci+di)*xi2-2*di*si*xi+di*si 其中si表示i進行的總常數,xi表示勝場數(也就是規定的流量)。顯然這樣的式子是不能定費用的,但我們可以求一下每增加1的流量費用的改變量:f(xi)-f(xi-1)=(ci+di)*(2*xi-1)-2*di*si 這樣我們可以把每1單位的流量設定乙個費用,也就是把原來一條邊拆成若干條邊,第i條邊如果對應第wi個勝場,那麼它的費用應該是(ci+di)*(2*wi-1)-2*di*si,注意這裡wi是第i個勝場,是要算上已經確定的勝場數的。
這樣建好圖,跑spfa或者zkw就行了,但是zkw要注意一點,就是有負費用邊!
zkw裡面dis頂標的意義是匯點出發到各點的最短路(以容量大於0的邊的費用為邊權),那麼有負費用的話頂標就不能初始化為0了,而應該是乙個負值。於是我們需要spfa來初始化一下頂標。這樣做麻煩了不少,不過還是有意義的:我這個題一下子跑到了rank1......
1 #include2 #include3 #include4 #include5 #include6 #include7income#define maxn 6200
8#define maxm 52000
9#define inf 2147483647
10using
namespace
std;
11struct
et12
e[maxm];
15int
dis[maxn],fir[maxn],q[maxn],v[maxn],sum[maxn],win[maxn],lose[maxn],d[maxn],c[maxn];
16bool
inque[maxn];
17int
n,m,tot,st,ed;
18long
long
ans;
1920
void
prepare()
2136
}37 inque[now]=0;38
}39}40
41int dfs(int now,int
flow)
4248 v[now]=1;49
int sap=0;50
for (int j=fir[now];j;j=e[j].next)
5161}62
return
sap;63}
6465
bool
adjust()
6674
if (tmp==inf) return0;
75for (int i=st;i<=ed;i++)
76if (v[i]) dis[i]+=tmp;
77return1;
78}7980
void add(int x,int y,int z,int
w)81
8586
intmain()
8795
intx,y;
96for (int i=1;i<=m;i++)
97104
for (int i=1;i<=n;i++)
105for (int j=win[i]+1;j<=sum[i]-lose[i];j++)
106 add(m+i,ed,1,(c[i]+d[i])*(2*j-1)-2*d[i]*sum[i]);
107//
for (int i=2;i<=tot;i++) cout<108
//計算初始收益
109for (int i=1;i<=n;i++)
110 ans+=c[i]*win[i]*win[i]+d[i]*(sum[i]-win[i])*(sum[i]-win[i]);
111prepare();
112do
113do memset(v,0,sizeof
(v));
114while
(dfs(st,inf));
115while
(adjust());
116 printf("
%lld\n
",ans);
117return0;
118 }
貼個zkw的**
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...