洛谷P4016 負載平衡問題

2021-08-15 10:54:18 字數 1452 閱讀 1248

問題描述

有乙個由n個沿環形鐵路分布的倉庫,每個倉庫有一定的貨物,某乙個倉庫可以往兩邊的倉庫運送貨物,求使n個倉庫貨物相等時的最小運輸量。

怎麼做?

這道題有很多做法,有貪心的,有二分的,有網路流的,其他的演算法相信同學們可以在其他的題解上看到,所以在這裡主要講一下網路流的做法。其實這是一道最小費用最大流的很好的題。 解法

我們以一批貨物從原始倉庫到目標倉庫所經過的倉庫個數作為費用,以這批貨物的大小作為流量,那麼這時的運輸量就是費用*流量。沒錯,如果想出了這個公式,我們就可以很快地解出這道題。

1.我們先拆點,因為如果只有乙個點會很難建圖。現在對於倉庫i有i和i』兩個點,i為貢獻點,i』為需求點。

2.如果數量-平均值<0,那麼這個點只可能是需求點,所以i』到t連一條流量為平均值-數量,費用為0。

3.如果數量-平均值》0,那麼這個點只可能是貢獻點,所以s到i連一條流量為數量-平均值,費用為0。

4.中間的點就i的貢獻點到左右的需求點

連一條流量為無限,費用為1的邊,因為這批貨物在這裡出現新一次的轉移。

5.有很多同學想問,你這樣滿足的只是兩個相鄰點之間的貨物轉移,不能滿足跨點運輸。對!所以我們在貢獻點之間連一條流量為無限,費用為1的邊,因為在這裡,貨物進行新一次的轉移。

最後跑一遍最小費用最大流,把流量*費用的總和輸出就行。

這裡的最大流保證了每個倉庫都滿足要求,最小費用則保證了運輸量最小。

貼**,我的**風可能會引起不適。

#include#include#includestruct edge;

edge s[1010];

int n;

int p[110];

int tot=0;

int len=1;

int f[1010];

int st=1,ed=2;

int sum[1010],mmin[1010],ip[1010];

int first[1010];

int begin=0,end;

bool tf[1010];

int min(int x,int y)

}} st++;

} if(sum[end]==1061109567) return 0;

flow+=mmin[end];

cost+=mmin[end]*sum[end];

int u=end;

while(u!=begin)

return 1;

}int cost_flow()

int main()

tot/=n;

end=2*n+1;

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

else

if(i+1<=n)

else

}int ans=cost_flow();

printf("%d\n",ans);

}

洛谷 P4016 負載平衡問題

題目描述 g 公司有 n 個沿鐵路運輸線環形排列的倉庫,每個倉庫儲存的貨物數量不等。如何用最少搬運量可以使 n 個倉庫的庫存數量相同。搬運貨物時,只能在相鄰的倉庫之間搬運。輸入輸出格式 輸入格式 檔案的第 1 行中有 1 個正整數 n,表示有 n 個倉庫。第 22 行中有 n 個正整數,表示 n 個...

洛谷 P4016 負載平衡問題

第一眼看見覺得和均分紙牌差不多,然而因為這是環形的,並不能用均分紙牌的方法做,但是均分紙牌的思想仍然適用 首先我們假設平均數為sum1。那麼對於第1個人,我們假設他給第n個人k個糖果,第2個人給1 第3個人給2 第n個人給第n 1個人 那麼對於第1個人給完n,第2個人給完1,第乙個人不會再改變糖果數...

洛谷P4016 負載平衡問題

g公司有 n個沿鐵路運輸線環形排列的倉庫,每個倉庫儲存的貨物數量不等。如何用最少搬運量可以使 n 個倉庫的庫存數量相同。搬運貨物時,只能在相鄰的倉庫之間搬運。輸入格式 檔案的第 1行中有 1個正整數 n,表示有 n 個倉庫。第 2行中有 n 個正整數,表示 n 個倉庫的庫存量。輸出格式 輸出最少搬運...