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