codevs1028 花店櫥窗布置(費用流)

2022-04-30 20:51:12 字數 2786 閱讀 2901

這幾天剛學了費用流,找到了這道題來練一練手。

題目:題目描述 description

假設以最美觀的方式布置花店的櫥窗,有f束花,v個花瓶,我們用美學值(乙個整數)表示每束花放入每個花瓶所產生的美學效果。為了取得最佳的美學效果,必須使花的擺放取得最大的美學值。

輸入描述 input description

第一行為兩個整數f,v(f<=v<=100)

接下來f行每行v個整數,第i行第j個數表示第i束花放入第j個花瓶的美學值。

輸出描述 output description

乙個整數,即最大美學值。

樣例輸入 sample input

2 210 0

5 2樣例輸出 sample output

12這道題很明顯是二分圖的最大權匹配,可以用最大費用最大流來做。做法:首先先建圖,在源點到每束花之間連一條流量為1,花費0為的點(每束花只能用一次),在每個花屏到匯點之間連一條流量為1,花費為0的邊(每個花瓶只能用一次),然後再在每束花和每個花瓶之間連一條流量為1,權值為這種匹配的美學值的邊;然後就用spfa找增廣路,建反向邊時,反向邊的流量是這條增廣路的流量,花費是原邊的花費的相反數。

一開始寫的時候受了最大流的影響,也像最大流那樣建了分層圖,於是wa了兩次也找不出錯。後來把分層圖刪掉才能ac。其實分層圖的作用就是避免出現環造成死迴圈,而用spfa來找增廣路,就已經避免了這個問題,反而會把原圖中的一些邊刪掉,所以費用流中千萬不要用分層圖

**:

var a,c:array[0..210,0..210]of longint;//a是原圖,c是花費的圖

fa,d:

array[0..210]of longint;//fa[i]是在到i的最短路徑上i的前乙個點(前驅結點),d[i]是到i的最短路徑的距離

b:array[0..210]of boolean;//記錄是否在佇列中

q:array[0..40010]of longint;//佇列

n,m,i,j,k,p,t,h,sum:longint;

procedure spfa(s:longint);//spfa模板

vari,h,t:longint;

begin

for i:=0

to n do

begin

d[i]:=-1

<<25; b[i]:=true;//初始化

end; h:=1; t:=1; q[1]:=s; d[s]:=0; b[s]:=false; fa[s]:=-1;//初始化2

repeat

for i:=0

to n do

if(a[q[h],i]>0)and(d[q[h]]+c[q[h],i]>d[i])then

begin//判斷是否有邊,是否更優

d[i]:=d[q[h]]+c[q[h],i]; fa[i]:=q[h];//更新距離

if b[i] then

begin

inc(t); q[t]:=i; b[i]:=false;//入隊

end;

end;

b[q[h]]:=true; inc(h);//出隊

until h>t;

end;

function

flow(s,t:longint):longint;

varp,min:longint;

begin

spfa(s);

if d[t]=-1

<<25

then exit(0);//判斷是否有增廣路

p:=t; min:=1

<<25;

while fa[p]>=0

dobegin

if min>a[fa[p],p] then min:=a[fa[p],p];//從匯點訪問到源點,計算流量

p:=fa[p];

end; p:=t;

while fa[p]>=0

dobegin

c[p,fa[p]]:=-c[fa[p],p];//建反向邊1

a[fa[p],p]:=a[fa[p],p]-min; a[p,fa[p]]:=a[p,fa[p]]+min;//建反向邊2

p:=fa[p];

end; sum:=sum+d[t];//加上這次增廣的花費,更新答案

exit(min);

end;

begin

read(n,m);

for i:=1

to n do

begin

a[0,i]:=1; c[0,i]:=0;//建圖1

end;

for i:=1

to m do

begin

a[i+n,n+m+1]:=1; c[i+n,n+m+1]:=0;//建圖2

end;

for i:=1

to n do

for j:=1

to m do

begin

read(k); a[i,n+j]:=1; c[i,n+j]:=k;//建圖3

end;

n:=n+m+1; sum:=0; k:=1;

while k>0

do k:=flow(0,n);//一行費用流

writeln(sum);//輸出最大美學值

end.

view code

codevs1028 花店櫥窗布置

假設以最美觀的方式布置花店的櫥窗,有f束花,v個花瓶,我們用美學值 乙個整數 表示每束花放入每個花瓶所產生的美學效果。為了取得最佳的美學效果,必須使花的擺放取得最大的美學值。第一行為兩個整數f,v f v 100 接下來f行每行v個整數,第i行第j個數表示第i束花放入第j個花瓶的美學值。乙個整數,即...

AC日記 花店櫥窗布置 codevs 1028

題目描述 description 假設以最美觀的方式布置花店的櫥窗,有f束花,v個花瓶,我們用美學值 乙個整數 表示每束花放入每個花瓶所產生的美學效果。為了取得最佳的美學效果,必須使花的擺放取得最大的美學值。輸入描述 input description 第一行為兩個整數f,v f v 100 接下來...

1028 花店櫥窗布置

時間限制 1 s 空間限制 128000 kb 題目等級 鑽石 diamond 題解假設以最美觀的方式布置花店的櫥窗,有f束花,v個花瓶,我們用美學值 乙個整數 表示每束花放入每個花瓶所產生的美學效果。為了取得最佳的美學效果,必須使花的擺放取得最大的美學值。輸入描述 input descriptio...