費用流 作業分配

2021-08-21 10:44:43 字數 1768 閱讀 7220

暑假裡,總有某些同學由於貪玩而忘記做作業。這些人往往要等到暑假快結束時才想起堆積如山的作業,但在這最後幾天的時間裡把這些作業做完已經不太現實了,於是「志同道合」的他們想出了乙個妙招。

假設現在有n科作業,他們把第i科作業按作業量平均分成ai份,他們總共有m個人,第j個人只願意做其中任意的bj份作業,而且我們知道ai的和等於bj的和,以及把第i科作業的其中乙份給第j個人做的時間是ci,j。現在他們想分配下各自的任務,一起把作業做完,然後再%#^&%^&#%%&^

現在的問題來了,他們希望所有人做作業的總時間的和最小,你能幫助他們解決問題嗎?

input

輸入檔案的第一行有兩個n,m表示有多少科作業和多少個人,第二行有n個數依次表示ai,第三行有m個數依次表示bj,最後n行,每行m個數表示ci,j。

output

輸出檔案包含一行為最少的時間總和。

sample input

2 2

3 5

5 3

1 2

2 1sample output

10 【樣例解釋】

第1個人做完所有的第1科作業以及第2科作業的其中2份,第2個人把第2科另外3份做完。

data constraint

第乙個點 n<=5 m<=5 ai,bi<=15 sum(ai)<=20

第二個點 n<=10 m<=10 ai,bi<=20 sum(ai)<=100

第三個點 n<=30 m<=30 ai,bi<=600 sum(ai)<=10000

第四個點到第十個點 n<=200 m<=200 ai,bi<=10000 sum(ai)<=1000000

容易看出費用流,但是時限500ms跑不過去,加了乙個玄學優化:動態加邊可以優化1500ms,從而ac

#include 

#include

#include

#include

#include

#define rep(i,a,b) for (i=a;i<=b;i++)

const

int n=501;

const

int oo=1061109567;

using

namespace

std;

struct edge g[2*n*n];

struct edge_notadd e[n][n];

int ecnt[n],pt[n];

int cnt=1,list[n];

int n,m,s,t;

int d[n],f[n];

int ans;

bool cmp(edge_notadd a,edge_notadd b)

bool spfa()

b[u]=0;

}return d[t]void mcf()

ans+=cost*mf;x=t;

while (f[x])

int i;

rep(i,1,n)

while (!g[pt[e[i][ecnt[i]].v]].c&&ecnt[i]void dinic()

int main()

rep(i,1,m)

rep(i,1,n)

sort(e[i]+1,e[i]+m+1,cmp);

add(i,e[i][1].v,oo,e[i][1].c);

ecnt[i]=1;

}dinic();

printf("%d",ans);

}

網路流 費用流

這個好像不考 沒事可以騙分 費用流,顧名思義,就是有費用的流,也就是說,給乙個網路流圖中的每條弧增加乙個單位流量費用。一般來說求解的費用流都是最大流最小費用。好像沒什麼好bb的 這裡推薦使用zkw演算法求解最小費用流,看著 理解就行,應該還是很好理解的。zkw演算法在稠密圖上跑得飛快,在稀疏圖上還不...

網路流 費用流

網路流有很多種類 其中最大流 有增廣路演算法和預流推進演算法。增廣路演算法就是不斷的新增增廣路。其中的dinic演算法。會稍微提到isap演算法 poj1273 首先想到dfs一直往後延伸,然後從源點到匯點計算每條路,但是這樣只是單條路的最值,有時可能因為走一條路而間接的認定了除這條路以外的某個路通...

費用流模板

const int oo 1e9 無窮 const int mm 11111111 邊 const int mn 888888 點 int node,src,dest,edge int ver mm flow mm cost mm nex mm int head mn dis mn p mn q m...