zoukankan      html  css  js  c++  java
  • POJ

    题目链接

    题意:

    给定$M$个猪圈,一开始这些都是上了锁的;

    现在$Mike$知道所有要来买猪的顾客的信息:

    $1.$顾客拥有的钥匙。

    $2.$顾客想要购买的数量。

    销售过程为:当每个顾客到来的时候,他将他拥有钥匙的猪圈全部打开,$Mike$从这些猪圈中挑选一些猪卖给他们;

    如果$Mike$愿意,他可以重新分配这些被打开的猪圈中的猪,顾客离开时,这些猪圈将被再次锁上,计算$Mike$卖出猪的最大数目。

    思路:

    设定超级源点和汇点,然后将第一次访问该猪圈的顾客与源点相连,流量为猪圈中猪的数目

    顾客$x$紧跟顾客$y$之后打开某个猪圈,那么就将两者相连,流量为$inf$(因为在这之前$Mike$有机会调整)

    将每个顾客与汇点相连,流量为改顾客想买的猪的数量。

      1 /*
      2 *  Author: windystreet
      3 *  Date  : 2018-08-16 11:29:37
      4 *  Motto : Think twice, code once.
      5 */
      6 #include <stdio.h>
      7 #include <algorithm>
      8 #include <string.h>
      9 #include <vector>
     10 #include <queue>
     11 
     12 using namespace std;
     13 
     14 #define X first
     15 #define Y second
     16 #define eps  1e-5
     17 #define gcd __gcd
     18 #define pb push_back
     19 #define PI acos(-1.0)
     20 #define lowbit(x) (x)&(-x)
     21 #define bug printf("!!!!!
    ");
     22 #define mem(x,y) memset(x,y,sizeof(x))
     23 
     24 typedef long long LL;
     25 typedef long double LD;
     26 typedef pair<int,int> pii;
     27 typedef unsigned long long uLL;
     28 
     29 const int maxn = 1e3+7;
     30 const int INF  = 1<<30;
     31 const int mod  = 1e9+7;
     32 struct Edge{
     33      int from,to,cap,flow;
     34 };
     35 int f[maxn];           // 记录前一个访问过该猪圈的人
     36 int pig[maxn];         // 记录每个猪圈原来有多少猪
     37 vector<int>v[maxn];    // 记录每个人有的钥匙
     38 struct Dinic
     39 {
     40     int n,m,s,t;
     41     vector<Edge>edge;
     42     vector<int>G[maxn];
     43     bool vis[maxn];
     44     int d[maxn];
     45     int cur[maxn];
     46     void init(int n){
     47         this->n = n;
     48         for(int i=0;i<=n;i++)G[i].clear(),edge.clear();
     49     }
     50     inline void addedge(int from,int to,int cap){
     51         edge.pb((Edge){from,to,cap,0});
     52         edge.pb((Edge){to,from,0,0});
     53         m = edge.size();
     54         G[from].pb(m-2);
     55         G[to].pb(m-1);
     56     }
     57     inline bool bfs(){
     58         mem(vis,0);
     59         queue<int>Q;
     60         Q.push(s);
     61         d[s] = 0;
     62         vis[s] = 1;
     63         while(!Q.empty()){
     64             int x = Q.front(); Q.pop();
     65             int sz = G[x].size();
     66             for(int i=0;i<sz;++i){
     67                 Edge &e = edge[G[x][i]];
     68                 if(!vis[e.to] && e.cap>e.flow){
     69                     vis[e.to] = 1 ;
     70                     d[e.to] = d[x] + 1;
     71                     Q.push(e.to); 
     72                 }
     73             }
     74         }
     75         return vis[t];
     76     }
     77     int dfs(int x,int a){
     78         if(x == t || a == 0)return a;
     79         int flow = 0,f;
     80         int sz = G[x].size();
     81         for(int &i = cur[x];i<sz;i++){
     82             Edge &e = edge[G[x][i]];
     83             if(d[x] + 1 == d[e.to] && (f = dfs(e.to,min(a,e.cap - e.flow)))>0){
     84                 e.flow += f;
     85                 edge[G[x][i]^1].flow -=f;
     86                 flow += f;
     87                 a -= f;
     88                 if(a==0)break;
     89             }
     90         }
     91         //if(!flow) d[x] = -2;  //炸点优化
     92         return flow;
     93     }
     94     inline int maxflow(int s,int t){
     95         this->s = s; this -> t = t;
     96         int flow = 0;
     97         while(bfs()){
     98             mem(cur,0);
     99             flow += dfs(s,INF);
    100         }
    101         return flow;
    102     }
    103 };
    104 Dinic dinic;
    105 
    106 void solve(){
    107     int n,m,x,y;
    108     scanf("%d%d",&m,&n);
    109     int S = 0,T = n +1;
    110     for(int i=1;i<=m;i++)scanf("%d",pig+i);
    111     for(int i=1;i<=n;i++){
    112         scanf("%d",&x);
    113         while(x--){
    114             scanf("%d",&y);
    115             v[i].pb(y);                     // 记录钥匙
    116         } 
    117         scanf("%d",&y); 
    118         dinic.addedge(i,T,y);              // 将每个人与汇点相连,流量为他需要买的猪
    119     }
    120     for(int i=1;i<=n;i++){
    121         int sz = v[i].size();
    122         for(int j=0;j<sz;j++){
    123             int id = v[i][j];
    124             if(!f[id]){                    // 若没有被访问过,则将该人和源点相连
    125                 f[id] = i;
    126                 dinic.addedge(S,i,pig[id]);
    127             }else{
    128                 dinic.addedge(f[id],i,INF);
    129                 f[id] = i;                 // 否则就将其与上一个访问的人相连
    130             }
    131         }
    132     }
    133     printf("%d
    ",dinic.maxflow(S,T));
    134     
    135     return;
    136 }
    137 
    138 int main()
    139 {
    140 //    freopen("F:\in.txt","r",stdin);
    141 //    freopen("out.txt","w",stdout);
    142 //    ios::sync_with_stdio(false);
    143     int t = 1;
    144     //scanf("%d",&t);
    145     while(t--){
    146     //    printf("Case %d: ",cas++);
    147         solve();
    148     }
    149     return 0;
    150 }
  • 相关阅读:
    [数据结构]图的DFS和BFS的两种实现方式
    [算法]两个栈实现一个队列
    [数据结构]手动实现队列
    [数据结构]手动实现栈
    [数据结构]手动实现单链表
    Hive分组取Top K数据
    HBase解决海量图片存储方案
    非结构化数据存储方案
    头条面试题之实现两个线程轮流打印字符串
    [算法]最大连续子数组和,最长重复子串,最长无重复字符子串
  • 原文地址:https://www.cnblogs.com/windystreet/p/9486738.html
Copyright © 2011-2022 走看看