Title Description
In summer vacation, there are always some students who forget to do their homework because of playing. These people often have to wait until the end of summer vacation to think of the pile of homework, but in the last few days to finish these homework is not realistic, so "like-minded" they came up with a clever idea.
Suppose that there are n subjects, they divide the i subjects into ai assignments according to the number of assignments, and they have m people in total. The j person is only willing to do any bj assignments, and we know that the sum of ai is equal to the sum of bj, and the time to do one of the i subjects to the j person is ci,j. Now they want to assign their own tasks, finish their homework together, and then% ^ &% ^ &%%%%&^
Now the problem is coming. They want everyone to spend the least time doing their homework. Can you help them solve the problem?
Input
The first line of the input file has two n's, m represents how many subjects and how many people there are, n represents ai in the second line, m represents bj in the third line, and N represents ci,j in the last line.
Output
The output file contains the minimum sum of times for a behavior.
Sample Input
2 2
3 5
5 3
1 2
2 1
Sample Output
10
[sample explanation]
The first person finished all the first homework and two of the second homework, and the second person finished the other three of the second homework.
Data Constraint
First point n < = 5 m < = 5 AI, Bi < = 15 sum (AI) < = 20
The second point n < = 10 m < = 10 AI, Bi < = 20 sum (AI) < 100
The third point n < = 30 m < = 30 AI, Bi < = 600 sum (AI) < 10000
From the fourth point to the tenth point n < = 200 m < = 200 AI, Bi < = 10000 sum (AI) < = 1000000
Analysis
It's easy to see the cost flow, but the time limit is 500ms, adding a metaphysical Optimization: dynamic edge adding can optimize 1500ms, thus AC
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <memory.h>
#define rep(i,a,b) for (i=a;i<=b;i++)
const int N=501;
const int oo=1061109567;
using namespace std;
struct Edge {
int u,v,c,w,nx;
}g[2*N*N];
struct Edge_notadd {
int v,c;
}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) {
return a.c<b.c;
}
void Add(int u,int v,int c,int w) {
g[++cnt].u=u;g[cnt].v=v;g[cnt].c=c;g[cnt].w=w;g[cnt].nx=list[u];list[u]=cnt;
g[++cnt].u=v;g[cnt].v=u;g[cnt].c=0;g[cnt].w=-w;g[cnt].nx=list[v];list[v]=cnt;
}
bool Spfa() {
queue<int> q;
bool b[N];
while (!q.empty()) q.pop();
q.push(s);
memset(d,0x3f,sizeof d);memset(b,0,sizeof b);memset(f,0,sizeof f);
d[s]=0;b[s]=1;
while (!q.empty()) {
int u=q.front();q.pop();
for (int i=list[u];i;i=g[i].nx)
if (g[i].c&&d[g[i].v]>d[u]+g[i].w) {
d[g[i].v]=d[u]+g[i].w;
f[g[i].v]=i;
if (!b[g[i].v])
q.push(g[i].v);
b[g[i].v]=1;
}
b[u]=0;
}
return d[t]<oo;
}
void Mcf() {
int x=t,cost=d[t],mf=oo;
while (f[x]) {
x=f[x];
mf=min(mf,g[x].c);
x=g[x].u;
}
ans+=cost*mf;x=t;
while (f[x]) {
x=f[x];
g[x].c-=mf;
g[x^1].c+=mf;
x=g[x].u;
}
int i;
rep(i,1,n)
while (!g[pt[e[i][ecnt[i]].v]].c&&ecnt[i]<m) {
ecnt[i]++;
Add(i,e[i][ecnt[i]].v,oo,e[i][ecnt[i]].c);
}
}
void Dinic() {
while (Spfa())
Mcf();
}
int main() {
int i,j;
scanf("%d%d",&n,&m);
s=n+m+1;t=n+m+2;
rep(i,1,n) {
int w;scanf("%d",&w);
Add(s,i,w,0);
}
rep(i,1,m) {
int w;scanf("%d",&w);
Add(n+i,t,w,0);
pt[n+i]=cnt-1;
}
rep(i,1,n)
{
rep(j,1,m)
{
int w;scanf("%d",&w);
e[i][j].v=n+j;
e[i][j].c=w;
}
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);
}