hdu 4322 最大費用最大流)

2021-09-06 11:48:28 字數 1783 閱讀 9500

思路:建圖真的是太巧妙了!直接copy大牛的了:

由於只要得到糖就肯定有1個快樂度,在這一點上醣的效果是等效的。所以只要考慮有特殊效果的糖的分配就可以了。

當快樂的程度超過b[i]時,多出來的部分就浪費了,為了使浪費盡可能少,我們用費用流加以控制,當獲得最大費用最大流的時候,這是的費用的利用率就是最高的。在建圖時只需考慮特殊的糖就可以了,建圖方法:

原點到每個糖:流為1,費用為0。如果糖對某個人有特殊效果,連邊:流為1,費用為0。人向匯點連邊:最終快樂的程度不超過b[i]的情況:流為b[i]/k,限制這樣的糖的數量,費用為k,因為特殊效果全部利用上了。快樂程度超過b[i]的情況:流為1,限制流量不超過b[i],費用為b[i] % k,因為多出來的快樂無效。當b[i] % k == 0時,這樣的邊沒有必要。當b[i] % k == 1時,這時的糖和普通的糖無異,沒必要連邊。

最終算出來的費用就是特殊的糖被充分利用後已經分配的快樂程度,最大流為為了達到這樣的程度使用的糖的數量,這樣就還剩n - 最大流數量的糖被我們當做普通的糖使用,只要剩下的普通的糖的數目大於還需填充的快樂程度,就可以滿足條件。

1 #include2 #include3 #include4 #include5 #include6

using

namespace

std;

7#define maxn 55

8#define maxm 4444

9#define inf 1<<30

1011

struct

edgeedge[maxm];

1415

intvs,vt,n,m,ne,sum,k;

16int

head[maxn];

1718

void insert(int u,int v,int cap,int

cost)

1932

33int

dist[maxn],pre[maxn],cur[maxn];

34bool

mark[maxn];

35bool spfa(int vs,int

vt)3656}

57}58}

59return dist[vt]!=-inf;60}

6162

int mincostflow(int vs,int

vt)63

70 flow+=aug,cost+=dist[vt]*aug;

71for(int u=vt;u!=vs;u=pre[u])75}

76return n-flow>=sum-cost;77}

7879

intlike[maxn][maxn];

80int

b[maxn];

81int

main()

8294

for(int i=1;i<=n;i++)insert(vs,i,1,0

);95

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

100 insert(i+n,vt,b[i]/k,k);

101if(b[i]%k>1

)104

}105 printf("

case #%d:

",t++);

106if

(mincostflow(vs,vt))else

109 puts("no"

);110

}111

return0;

112 }

view code

hdu 4322 Candy 最大費用最大流

很巧妙的建圖,沒有加成的糖對每個人都是一樣的所以建圖的時候只考慮加成的情況,以糖給人加的點數為費用,乙個人需要的點數為a則建一條由這個人指向匯的容量為a k費用為 k的邊,如果有餘數就再建一條容量為1費用為這個餘數的邊,由源向糖建邊,有加成效果的人和糖的組合之間連線,求這個圖的最小費用最大流即可。d...

hdu4322 Candy 最小費用最大流

題目描述 有n種糖果和m個小孩,每個小孩有乙個要求的愉悅度b i 給出乙個n m的like矩陣,若like i j 1說明i小孩喜歡j糖果,那麼如果 將j糖果分給i小孩則i小孩將獲得k點愉悅度,若like i j 0,那麼如果將i糖果分給j小孩,那麼i小孩將獲得1點愉悅度,求問有沒有糖果的分配方 案...

HDU4862 Jump(最大流量最大費用流)

題意 有n m的格仔,每乙個格仔包含乙個數字,0 9。你初始的能量為0,你可以玩k次,每乙個你可以選擇你現在的格仔的正下方或者正右方的任意乙個格仔跳,但必須是之前沒有跳過的格仔。每玩一次你都可以跳任意次。每跳一次,從 x1,y1 到 x2,y2 你將花費 x1 x2 y1 y2 1的能量,如果起止格...