poj 2516

来源:互联网 发布:手机地图导航软件 编辑:程序博客网 时间:2024/05/18 00:38

最小费用最大流。模板题,
听说驼峰体能提升逼格。。。


顺便说一句,数据范围有坑。


#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;}
0 0