POJ1149 PIGS 最大流 優化建模

2021-08-19 13:50:13 字數 2620 閱讀 8364

pigs

題目大意:

m m

個豬圈,每個豬圈內有一些豬,有

n' role="presentation" style="position: relative;">n

n名顧客陸續到來,他們每個人能夠開乙個集合內的豬圈,並且能從這些豬圈中買走至多bi

b

i頭豬,在這個時候,我們還能對這些豬圈內的豬進行調動,每個豬圈內可以裝無窮多頭豬,問最多一共能賣出多少頭豬。

做法:本題需要用到最大流+優化建模。

看到這題,乙個很顯然的思路是,對每一天建出

m m

個點表示這一天各豬圈內的豬,然後各種常規建圖後跑最大流,然而我們發現這個圖光點數就有nm

' role="presentation" style="position: relative;">nmn

m個了,邊就更多了,根本沒法做,因此我們要考慮優化我們的建模。

我們可以用「合併」的思想來減少圖中的點和邊。有以下三個顯然的結論:

1.如果一些點的入度**完全相同,那麼這些點能合併成乙個點。

2.如果一些點的出度指向完全相同,那麼這些點能合併成乙個點。

3.如果從乙個點到另乙個點有且僅有一條路徑,那麼可以把從這個點到另乙個點之間的路徑合併為一條從這個點到另乙個點的邊,容量為原路徑上容量的最小值。

當然,這些結論是用來幫助我們減小網路的複雜性,從而想到更好的建模方法,而不是讓我們在實際程式中用這些方法縮點。總之經過這些變換後,我們得到了乙個新的可以描述的模型,具體來說如下:

我們考慮每份從源點到匯點的流量都代表一頭豬被賣掉了,那麼原來在豬圈

i i

內的豬能在哪些時候被調動到哪些豬圈去呢?令第

i' role="presentation" style="position: relative;">i

i位顧客能開的豬圈集合為si

s

i,若si

s

i和sj

s

j相交,就表示第

i i

天時集合

i' role="presentation" style="position: relative;">i

i中的任何乙個豬圈中的豬能經過調動最終到達第

j j

天時集合sj

' role="presentation" style="position: relative;">sjs

j中的任何乙個豬圈,因此我們對每個顧客建乙個點,若si

s

i和sj

s

j相交則從顧客

i i

到顧客j' role="presentation" style="position: relative;">j

j連一條容量為正無窮的邊(具體建模時操作略有不同,但是和這樣建邊等價,詳見**)。這樣只要能從乙個顧客走到另乙個顧客,就表示到顧客

i i

時能賣的豬,到顧客

j' role="presentation" style="position: relative;">j

j時也能賣。特別地,我們要從源點向每個顧客連一些邊,連邊方式為:如果豬圈

i i

第一次被開是在第

j' role="presentation" style="position: relative;">j

j天,那麼從源點向顧客

j j

連一條容量為一開始豬圈

i' role="presentation" style="position: relative;">i

i中的豬數。最後顯然,我們要從每個顧客向匯點連一條容量為他想買的豬數的邊。對這個網路跑乙個最大流即可。

我們發現優化後的建模僅包含n+

2 n+2

個點,是非常優的,因此我們能通過此題。

以下是本人**:

#include 

using

namespace

std;

const

int inf=1000000000;

int m,n,s,t,p[1010],last[1010];

int first[110]=,tot=1;

int lvl[110],cur[110],q[110],h,t;

bool vis[110];

struct edge

e[100010];

void insert(int a,int b,int f)

void init()

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

last[x]=i;

}scanf("%d",&b);

insert(i,t,b);

}} bool makelevel()

}return lvl[t]!=-1;

}int maxflow(int v,int maxf)

cur[v]=i;

}if (!ret) lvl[v]=-1;

return ret;

}void dinic()

int main()

POJ 1149 PIGS 用了三種求最大流的方法

第一道最大流,寫的有點挫,按照ford演算法來做 也沒用什麼改進的最短增廣演算法 轉化為網路流的模型時稍微有點麻煩 include include include include using namespace std define maxn 1005 define inf 9999999 defi...

POJ1149 養豬(最大流)

題目描述 尼克在一家養豬場工作,這家養豬場共有m間鎖起來的豬舍,由於豬舍的鑰匙都給了客戶,所以尼克沒有辦法開啟這些豬舍,客戶們從早上開始乙個接乙個來購買生豬,他們到達後首先用手中的鑰匙開啟他所能開啟的全部豬舍,然後從中選取他要買的生豬,尼克可以在此期間將開啟的豬舍中的豬調整到其它開著的豬舍中,每個豬...

PIGS POJ 1149 水最大流

題意 有m個豬圈,每個豬圈裡初始時有若干頭豬。一開始所有豬圈都是關閉的。依次來了n個顧客,每個顧客分別會開啟指定的幾個豬圈,從中買若干頭豬。每個顧客分別都有他能夠買的數量的上限。每個顧客走後,他開啟的那些豬圈中的豬,都可以被任意地調換到其它開著的豬圈裡,然後所有豬圈重新關上。問總共最多能賣出多少頭豬...