UVALIVE 3562 Remember the A La Mode!

费用流 建图很简单直接上代码

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
#define MAXN 110
#define MAXD 50000
const int INF = 0x3f3f3f3f;
int P,I;
int G[MAXN][MAXN];
queue<int>q;
struct node
{
        int u,v,next;
        int cap,flow,cost;
}edge[MAXD];
int cnt,src,tag;
int head[MAXN];
int p[MAXN],d[MAXN];
bool inq[MAXN];
int nump[MAXN],numi[MAXN];
void addedge(int u ,int v, int cap ,int cost)
{
        edge[cnt].u = u;
        edge[cnt].v = v;
        edge[cnt].flow = 0;
        edge[cnt].cap = cap;
        edge[cnt].cost = cost;
        edge[cnt].next = head[u];
        head[u] = cnt++;

        edge[cnt].v = u;
        edge[cnt].u = v;
        edge[cnt].flow= 0;
        edge[cnt].cap = 0;
        edge[cnt].cost = - cost;
        edge[cnt].next = head[v];
        head[v] = cnt++;
}
bool SPFA(int s,int t)
{
        while (!q.empty()) q.pop();
        memset(inq,false,sizeof(inq));
        memset(d,0x3f,sizeof(d));
        memset(p,-1,sizeof(p));
        inq[s] = true; d[s] = 0;
        q.push(s);
        while (!q.empty())
        {
                int u = q.front();q.pop();
                inq[u] = false;
                for (int  i = head[u] ; i != - 1; i = edge[i].next)
                {
                        int v = edge[i].v;
                        if (d[v] > d[u] + edge[i].cost && edge[i].cap > edge[i].flow)
                        {
                                d[v] = d[u] + edge[i].cost;
                                p[v] = i;
                                if (!inq[v])
                                {
                                        inq[v] = true;
                                        q.push(v);
                                }
                        }
                }
        }
        return d[t] != INF;
}
int  slove()
{
      int C = 0 ,F = 0;
      while (SPFA(src,tag))
      {
              int a = INF;
              for (int i = p[tag]; i != -1 ; i = p[edge[i].u]) a = min(a,edge[i].cap - edge[i].flow);
              for (int i = p[tag]; i != -1; i = p[edge[i].u])
              {
                      edge[i].flow += a;
                      edge[i ^ 1].flow -= a;
              }
              C += d[tag] * a;
              F += a;
      }
      return C;
}
int main()
{
        //freopen("sample.txt","r",stdin);
        int kase = 1;
        while (scanf("%d%d",&P,&I) != EOF)
        {
                if (P == 0 && I == 0) break;
                for (int i = 1; i <= P; i++)scanf("%d",&nump[i]);
                for (int i = 1; i <= I; i++) scanf("%d",&numi[i]);
                cnt = 0;
                memset(head ,-1 ,sizeof(head));
                src = 0;
                tag = P + I + 1;
                for (int i = 1 ;i <= P; i++)
                        for (int j = 1; j <= I; j++)
                {
                        double tmp;
                        scanf("%lf",&tmp);
                        if (tmp < - 0.5) G[i][j] = -100;
                        else
                        {
                                tmp = (tmp * 100 + 0.5);
                                G[i][j] = (int) tmp;
                        }
                }
                int retmin,retmax;
                for (int i = 1; i <= P; i++) addedge(src,i,nump[i],0);
                for (int i = 1; i <= I; i++) addedge(P + i , tag ,numi[i],0);
                for (int i = 1; i <= P; i++)
                        for (int j = 1; j <= I; j++)
                {
                        if (G[i][j] == -100) continue;
                        addedge(i , P + j ,INF,G[i][j]);
                }
                retmin = slove();
                cnt = 0;
                memset(head,-1,sizeof(head));
                for (int i = 1; i <= P; i++) addedge(src,i,nump[i],0);
                for (int i = 1; i <= I; i++) addedge(P + i , tag ,numi[i],0);
                for (int i = 1; i <= P; i++)
                        for (int j = 1; j <= I; j++)
                {
                        if (G[i][j] == -100) continue;
                        addedge(i , P + j ,INF,-G[i][j]);
                }
                retmax = -1 * slove();
                printf("Problem %d: %.2lf to %.2lf\n",kase++,(double)retmin / 100.0,(double) retmax / 100.0);
        }
        return 0;
}

 

posted @ 2014-10-29 17:34  Commence  阅读(538)  评论(0编辑  收藏  举报