zoukankan      html  css  js  c++  java
  • poj 1149 PIGS(最大流经典构图)

    题目描述:
    迈克在一个养猪场工作,养猪场里有M 个猪圈,每个猪圈都上了锁。由于迈克没有钥匙,所
    以他不能打开任何一个猪圈。要买猪的顾客一个接一个来到养猪场,每个顾客有一些猪圈的钥匙,
    而且他们要买一定数量的猪。某一天,所有要到养猪场买猪的顾客,他们的信息是要提前让迈克
    知道的。这些信息包括:顾客所拥有的钥匙(详细到有几个猪圈的钥匙、有哪几个猪圈的钥匙)、
    要购买的数量。这样对迈克很有好处,他可以安排销售计划以便卖出的猪的数目最大。
    更详细的销售过程:当每个顾客到来时,他将那些他拥有钥匙的猪圈全部打开;迈克从这些
    猪圈中挑出一些猪卖给他们;如果迈克愿意,迈克可以重新分配这些被打开的猪圈中的猪;当顾
    客离开时,猪圈再次被锁上。注意:猪圈可容纳的猪的数量没有限制。
    编写程序,计算迈克这一天能卖出猪的最大数目。

    构图:源点连接每一个猪圈的第一个打开的顾客,容量为该猪圈的猪数;

       下一次的顾客连接上一次的顾客,容量为INF;

       接着每个顾客连接到汇点,容量为该顾客所需猪数。

    这样构图是因为每一次打开猪圈猪可以重新分配,第一次打开猪圈的顾客可以把猪都流到他这里,再分流到下一个顾客或者汇点,这样就可以利用最大流来得到最优解。

      1 /*
      2  *Author:       Zhaofa Fang
      3  *Created time: 2013-07-17-10.23
      4  *Language:     C++
      5  */
      6 #include <cstdio>
      7 #include <cstdlib>
      8 #include <sstream>
      9 #include <iostream>
     10 #include <cmath>
     11 #include <cstring>
     12 #include <algorithm>
     13 #include <string>
     14 #include <utility>
     15 #include <vector>
     16 #include <queue>
     17 #include <map>
     18 #include <set>
     19 using namespace std;
     20 
     21 typedef long long ll;
     22 #define DEBUG(x) cout<< #x << ':' << x << endl
     23 #define FOR(i,s,t) for(int i = (s);i <= (t);i++)
     24 #define FORD(i,s,t) for(int i = (s);i >= (t);i--)
     25 #define REP(i,n) for(int i=0;i<(n);i++)
     26 #define REPD(i,n) for(int i=(n-1);i>=0;i--)
     27 #define PII pair<int,int>
     28 #define PB push_back
     29 #define MP make_pair
     30 #define ft first
     31 #define sd second
     32 #define lowbit(x) (x&(-x))
     33 #define INF (1<<30)
     34 #define eps 1e-8
     35 
     36 const int maxn = 505;
     37 const int maxm = 400011;
     38 
     39 struct Edge{
     40     int v,cap,flow,next;
     41 }edge[maxm];
     42 int eh[maxn],tot;
     43 bool vist[maxn];
     44 int d[maxn];
     45 
     46 void init(){
     47     tot = 0;
     48     memset(eh,-1,sizeof(eh));
     49 }
     50 void addedge(int u,int v,int c){
     51     Edge e = {v,c,0,eh[u]};
     52     edge[tot] = e;
     53     eh[u] = tot ++;
     54 }
     55 void add(int u,int v,int c){
     56     addedge(u,v,c);
     57     addedge(v,u,0);
     58 }
     59 bool BFS(int s,int t){
     60     memset(vist,0,sizeof(vist));
     61     queue<int>Q;
     62     Q.push(s);
     63     d[s] = 0;
     64     vist[s] = 1;
     65     while(!Q.empty()){
     66         int u = Q.front();
     67         Q.pop();
     68         for(int i=eh[u];i!=-1;i=edge[i].next){
     69             int v = edge[i].v;
     70             if(!vist[v] && edge[i].cap > edge[i].flow){
     71                 vist[v] = 1;
     72                 d[v] = d[u] + 1;
     73                 if(v == t)return true;
     74                 Q.push(v);
     75             }
     76         }
     77     }
     78     return false;
     79 }
     80 int DFS(int u,int t,int avi){
     81     if(u == t || avi == 0)return avi;
     82     int flow = 0 , f;
     83     for(int i=eh[u];i!=-1;i=edge[i].next){
     84         int v = edge[i].v;
     85         if(d[v] == d[u] + 1 && (f=DFS(v,t,min(avi,edge[i].cap-edge[i].flow)))>0){
     86             edge[i].flow += f;
     87             edge[i^1].flow -= f;
     88             flow += f;
     89             avi -= f;
     90             if(avi == 0)break;
     91         }
     92     }
     93     return flow;
     94 }
     95 int maxFlow(int s,int t){
     96     int flow = 0;
     97     while(BFS(s,t))flow += DFS(s,t,INF);
     98     return flow;
     99 }
    100 int pig[maxn],last[maxn];
    101 int main(){
    102     //freopen("in","r",stdin);
    103     //freopen("out","w",stdout);
    104     int n,m;
    105     while(~scanf("%d%d",&m,&n)){
    106         int A,B,u,v;
    107         init();
    108         FOR(i,1,m)scanf("%d",&pig[i]);
    109         memset(last,0,sizeof(last));
    110         FOR(i,1,n){
    111             scanf("%d",&A);
    112             REP(j,A){
    113                 scanf("%d",&u);
    114                 if(!last[u])add(0,i,pig[u]);
    115                 else add(last[u],i,INF);
    116                 last[u] = i;
    117             }
    118             scanf("%d",&B);
    119             add(i,n+1,B);
    120         }
    121         printf("%d
    ",maxFlow(0,n+1));
    122     }
    123     return 0;
    124 }
    View Code
  • 相关阅读:
    SQL函数 Convert,dateadd
    WebBrowser.ExecWB的完整说明
    GetShortPathName函数
    winmm.dll包含函数
    C# 操作Excel大全
    C#操作目录和文件
    File操作
    C#中对EXCEL保存的SAVEAS方法说明
    dataTable 、dataView、Dataset 区别
    System.Windows.Forms.Application.DoEvents();
  • 原文地址:https://www.cnblogs.com/fzf123/p/3196101.html
Copyright © 2011-2022 走看看