zoukankan      html  css  js  c++  java
  • POJ 2516 Minimum Cost 最小费用最大流 费用流

    题目连接:http://poj.org/problem?id=2516

    题意跟题目输入这里写的很明白:http://blog.csdn.net/lyy289065406/article/details/6742534

    无非就是k种物品,直接对每种物品进行一次最大流就OK了~

    View Code
      1 #include <iostream>
      2 #include <queue>
      3 #include <iostream>
      4 #include <cstdio>
      5 #include <cstring>
      6 #include <vector>
      7 using namespace std;
      8 const int maxn = 350;
      9 const int inf = 10000000;
     10 struct node
     11 {
     12     int u,v,cap,flow,cost;
     13 };
     14 
     15 vector<struct node> edge;
     16 vector<int> g[maxn];
     17 
     18 void init(int n)
     19 {
     20     int i;
     21     for(i = 0;i <= n;i++)
     22     g[i].clear();
     23     edge.clear();
     24 
     25     return ;
     26 }
     27 void addedge(int u,int v,int cap,int flow,int cost)
     28 {
     29     edge.push_back((struct node){u,v,cap,flow,cost});
     30     edge.push_back((struct node){v,u,0,flow,-cost});
     31     int m;
     32     m = edge.size();
     33     g[u].push_back(m-2);
     34     g[v].push_back(m-1);
     35 }
     36 int shop[55][55];
     37 int supply[55][55];
     38 int vis[maxn],a[maxn],pre[maxn],dis[maxn];
     39 int spfa(int s,int t,int n,int &flow,int & cost)
     40 {
     41     int i;
     42     queue <int >q;
     43     for(i = 0;i <= n;i++)
     44     dis[i] = inf;
     45     dis[s] = 0;
     46     pre[s] = 0;memset(vis,0,sizeof(vis));
     47     vis[s] = 1;
     48     a[s] = inf;
     49 
     50     int u,v;
     51     q.push(s);
     52 
     53     while(!q.empty())
     54     {
     55         u = q.front();
     56         q.pop();
     57         vis[u] = 0;
     58 
     59         for(i = 0;i < g[u].size();i++)
     60         {
     61             struct node& e = edge[g[u][i]];
     62             v = e.v;
     63             if(e.cap > e.flow &&dis[v] > dis[u] + e.cost)
     64             {
     65                 dis[v] = dis[u]+e.cost;
     66                 a[v] = min(a[u],e.cap-e.flow);
     67                 pre[v] = g[u][i];
     68                 if(!vis[v])
     69                 {
     70                     vis[v] = 1;
     71                     q.push(v);
     72                 }
     73             }
     74         }
     75     }
     76     if(dis[t] == inf)
     77     return 0;
     78 
     79     flow += a[t];
     80     cost += dis[t]*a[t];
     81 
     82     u = t;
     83     while( u != s)
     84     {
     85         edge[pre[u]].flow += a[t];
     86         edge[pre[u]^1].flow -= a[t];
     87         u = edge[pre[u]].u;
     88     }
     89     return 1;
     90 }
     91 
     92 int MCMF(int s,int t,int n)
     93 {
     94     int flow = 0,cost = 0;
     95     while(spfa(s,t,n,flow,cost));
     96     return cost;
     97 }
     98 int main()
     99 {
    100     int n,m,k;
    101     while (scanf("%d %d %d",&n,&m,&k)&&(n||m||k))
    102     {
    103         int i,j;
    104         for(i = 1;i <= n;i++)
    105         {
    106             for(j = 1;j <= k;j++)
    107             cin>>shop[i][j];
    108         }
    109 
    110         for(j = 1;j <= m;j++)
    111         for(i = 1;i <= k;i++)
    112         cin>>supply[j][i];
    113 
    114         int leap = 1;
    115         for(i = 1;i <= k;i++)
    116         {
    117             int need,support;
    118             need = support = 0;
    119 
    120             for(j = 1;j <= m;j++)
    121             support += supply[j][i];
    122 
    123             for(j = 1;j <= n;j++)
    124             need += shop[j][i];
    125 
    126             if(support < need)
    127             {
    128                 leap = 0;
    129                 break;
    130             }
    131         }
    132         int ii;
    133         int ans = 0;
    134         for(ii = 1;ii <= k;ii++)
    135         {
    136             init(n+m+2);
    137             for(i = 1;i <= m;i++)
    138             addedge(0,i,supply[i][ii],0,0);
    139 
    140             for(i = 1;i <= n;i++)
    141             addedge(i+m,n+m+1,shop[i][ii],0,0);
    142 
    143             for(i = 1;i <= n;i++)
    144             for(j = 1;j <= m;j++)
    145             {
    146                 int cost;
    147                 cin>>cost;
    148                 addedge(j,i+m,inf,0,cost);
    149             }
    150             if(leap)
    151             ans += MCMF(0,n+m+1,n+m+2);
    152         }
    153         if(leap)
    154         cout<<ans<<endl;
    155         else
    156         puts("-1");
    157 
    158     }
    159 
    160     return 0;
    161 }
  • 相关阅读:
    命令行解释器(shell)
    TensorFlow经典案例2:实现最近邻算法
    TensorFlow经典案例1:基本操作
    TensorBoard在谷歌浏览器显示找不到网页
    Pandas中的DataFrame.filter()
    【转】保证训练集和测试集取到和数据集中相同比例的类别
    数据分析小实践:统计每个国家存在心理健康问题的平均年龄
    TabActivity 切换Activity界面
    Android获取屏幕实际高度跟显示高度,判断Android设备是否拥有虚拟功能键
    非常简单的XML解析(SAX解析、pull解析)
  • 原文地址:https://www.cnblogs.com/0803yijia/p/2984424.html
Copyright © 2011-2022 走看看