最小费用最大流。模板题,
听说驼峰体能提升逼格。。。
顺便说一句,数据范围有坑。
#include<map>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<cmath>
#include<algorithm>
const int MAXM = 505, MAXN = 505, MAXK = 50, INF = 2e8;
const int NodeNum = MAXM+MAXN ,SIZE = MAXM*MAXN+MAXN+MAXM;
const int Ni[2] = {-1,1};
int n, m, k;
int sx[MAXK][MAXM] = {0};
int tx[MAXK][MAXN] = {0};
int mat[MAXM][MAXN] = {0};
struct Edge
{
int v,cap,co,next;
}edge[SIZE<<1];
int el, ind, head[NodeNum] = {0};
int s, t;
void NewEdge(int u,int v,int cap,int co)
{
++el;edge[el].v = v;
edge[el].cap = cap;
edge[el].co = co;
edge[el].next = head[u];
head[u] = el;
}
void NewNetEdge(int u,int v,int cap,int cost)
{
NewEdge(u,v,cap,cost);NewEdge(v,u,0,-cost);
}
int NewNode(){head[++ind] = 0;return ind;}
int mpot[MAXM], npot[MAXN] = {0};
std::pair<int,int>from[NodeNum];
#define Mp(x,y) std::make_pair(x,y)
#define Nn first
#define En second
int dist[NodeNum];bool flag[NodeNum];
int line[NodeNum],f,r;
void SPFA()
{
// memset(flag,false,sizeof(flag));
for(int i = 1; i <= ind; i++)dist[i] = INF;
f = r = dist[s] = 0;
line[r] = s, r = (r+1)%NodeNum, flag[s] = true;
while(f!=r)
{
int a = line[f]; f = (f+1)%NodeNum; flag[a] = false;
for(int i = head[a]; i ; i = edge[i].next)
if(edge[i].cap)
{
int p = edge[i].v , tmp = dist[a] + edge[i].co;
if(tmp < dist[p])
{
dist[p] = tmp,from[p] = Mp(a,i);
if(!flag[p])
{
if(dist[p] <= dist[line[f]])
f = (f-1+NodeNum)%NodeNum ,line[f] = p;
else
line[r] = p, r = (r+1)%NodeNum;
flag[p] = true;
}
}
}
}
}
int find(int now,int flow)
{
if(now == s)return flow;
int y = from[now].En;
flow = std::min(flow,edge[y].cap);
flow = find(from[now].Nn,flow);
edge[y].cap -= flow;
edge[y+Ni[y&1]].cap += flow;
return flow;
}
void NetFlow(int &totflow,int &totcost)
{
totflow = totcost = 0;
while(1)
{
SPFA(); if(dist[t] == INF)break;
int fflow = find(t,INF);
totflow += fflow;
totcost += fflow*dist[t];
}
}
void BuildGraph(int ss[],int tt[])
{
el = ind = 0;
s = NewNode(); t = NewNode();
for(int i = 1; i <= m ; i++)
{
mpot[i] = NewNode();
NewNetEdge(s,mpot[i],ss[i],0);
}
for(int i = 1; i <= n; i++)
{
npot[i] = NewNode();
NewNetEdge(npot[i],t,tt[i],0);
}
for(int i = 1; i <= m ;i++)
for(int j = 1; j <= n; j++)
NewNetEdge(mpot[i],npot[j],INF,mat[i][j]);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("poj2516.in","r",stdin);
freopen("poj2516.out","w",stdout);
#endif
while(1)
{
scanf("%d%d%d",&n,&m,&k);
if(!n && !m && !k) break;
for(int i = 1; i <= n ; i++)
for(int j = 1; j <= k; j++)
scanf("%d",&tx[j][i]);
for(int i = 1; i <= m ; i++)
for(int j = 1; j <= k; j++)
scanf("%d",&sx[j][i]);
int sigma = 0;
for(int i = 1; i <= k; i++)
{
for(int p = 1; p <= n; p++)
for(int q = 1; q <= m; q++)
scanf("%d",&mat[q][p]);
if(sigma == -1)continue;
BuildGraph(sx[i],tx[i]);
int flow,cost,sum = 0;
for(int p = 1; p <= n; p++)sum += tx[i][p];
NetFlow(flow,cost);
if(flow == sum)sigma += cost;
else sigma = -1;
}
printf("%d\n",sigma);
}
#ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
#endif
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。