題目鏈結
題目大意:
n 支球隊,球隊的支出和勝負場次有關,具體來說,第i支球隊的賽季總支出是ci
∗x2+
di∗y
2,其中x,
y 分別表示這只球隊本賽季的勝負場次。
現在賽季進行到了一半,每只球隊分別取得了ai
場勝利和bi
場失利。而接下來還有
m 場比賽要進行。問聯盟球隊的最小總支出是多少。
題解:輸贏都會帶來收益……
可以假設初始每只隊伍都輸,算出初始收益,然後對每場比賽分配贏的隊伍
這樣每場只要修改贏的那個隊伍的收益
從源向每場比賽連流量1費用
0 的邊,從比賽向這場比賽的兩支隊都連一條流量1費用
0 的邊
由於費用是動態變化的,考慮拆邊
對於某支球隊,假設後
m場中其參加
x 場,初始w=
ai,l
=bi+
x ,之後每贏一場w+
+,l–
− 每只隊向匯連x條邊,分別代表其贏i場比賽時相對贏i-1場時收益的增量,即 (c
∗(w+
1)2+
d∗(l
−1)2
)−(c
∗w2+
d∗l2
)=2w
∗c−2
l∗d+
c+d
收益隨勝利場數遞增,因此一定先走贏比賽場數較少的邊,可以保證正確性
答案為所有隊伍最初收益+最小費用最大流費用
我的收穫:動態費用拆邊建圖,差分費用……
#include
#include
#include
#include
#include
#include
using
namespace
std;
const
int n=7505;
const
int inf=1e9;
int n,m,ans;
int st,ed;
int t,head[n];
int q[n],l,r;
int win[n],lose[n],c[n],d[n];
int d[n],pre[n],in[n];
bool vis[n];
struct edgee[1000000];
void add(int i,int j,int ca,int co)
void insert(int i,int j,int w,int z)
bool spfa()}}
}return d[ed]!=inf;
}void mcfx()
}void work()
void build()
}void init()
for(int i=1;i<=n;i++) lose[i]+=in[i];
for(int i=1;i<=n;i++) ans+=win[i]*win[i]*c[i]+lose[i]*lose[i]*d[i];
build();
}int main()
JSOI2009 球隊收益
因為要限制每個比賽,一勝一負,流量無法限制。所以我們可以假設先全敗,然後選擇某個人獲勝,然後用差值來改變。假設當前a勝,b負。然後獲勝一次的差值為 c a 1 a 1 d b 1 b 1 c a a d b b c 2 a 1 d 2 b 1 ac pragma gcc optimize ofast...
JSOI2009 球隊收益 Solution
題意 有n nn個球隊,如果一支球隊勝場為x ix i xi 負場為y iy i yi 那麼他們的獎金即為ci xi2 di y i2 c i times x i 2 d i times y i 2 ci xi 2 d i y i2 現在知道了這些球隊現在的勝場和負場,以及一些不確定的比賽,問總獎金...
JSOI2009 bzoj1449 球隊收益
description input output 乙個整數表示聯盟裡所有球隊收益之和的最小值。首先假設全輸,然後給每場比賽分配乙個贏家,每個隊伍每多贏一場多獲得的收益作為費用。但是有乙個問題,如何保證每次走的是對應的邊?也就是,如何保證贏第一場的時候增加的收益是贏一場減贏零場,而不是贏兩場減贏一場?...