山东济南彤昌机械科技有限公司 山东济南江鹏工贸游有限公司

tyvj P1517 飘飘乎居士的乌龟(最大流)

                          P1517 飘飘乎居士的乌龟
                    时间: 1000ms / 空间: 131072KiB / Java类名: Main

背景

飘飘乎居士养了乌龟。当然,这些乌龟是用来出售赚取利润的。

描述

飘飘乎居士的乌龟被安置在了m个窝中。现在,飘飘乎居士已经接到了n个人的定购通知,他们会按顺序在来挑选乌龟,其中,第i个人会在pi个窝中挑选乌龟, 但最多只想买xi只乌龟。另外,在第i个人购买完乌龟以后,飘飘乎居士会将指定的qi个窝中的龟进行调整,他可以任意调换指定的qi个窝中乌龟数量。飘飘 乎希望知道,在n个人购买完乌龟后,他最多可以出售多少只乌龟?

输入格式

输入格式:第一行,两个正整数n、m。
          接下来一行m个整数(可能为0),第i个整数表示第i个窝中乌龟的数量。

          接下来输入分为n组,每组3行输入,第i组表示第i个人的信息:
第一行一个整数xi,表示第i个人最多购买的乌龟数量
第二行一个整数pi以及pi整数,表示该顾客会在pi个指定的窝中挑选乌龟
第三行一个整数qi(qi可能为0)以及跟着的qi个正整数,表示在第i个人购买完乌龟后,飘飘乎居士会调整这qi个窝中乌龟的数量。

输出格式

输出格式:一行,表示飘飘乎居士最多出售乌龟的数量。

测试样例1

输入

输入样例1:
2 4
2 2 5 0
3
1 3
2 1 4

10
2 4 3
0

输入样例2:
2 4
1 2 3 3
3
2 1 4
2 4 3

4
1 3
4 1 2 3 4

输出

输出样例1:
7
输出样例2:
7

备注

 Hint:样例一解释:飘飘乎居士4个窝,初始时,第一个窝里有2只乌龟,第二个窝里有2只乌龟,第三个窝里有5只乌龟;第四窝里没有乌龟,共有2位顾客来购买乌龟。
       在 第一位顾客到来时,他想在3号窝中挑选乌龟,最多只想买3只乌龟。飘飘乎居士将3号窝中的乌龟出售。出售以后,3号窝剩下2只乌龟,飘飘乎居士可以调整 1、4号窝中乌龟的数量,将1号窝中的2只乌龟转入4号窝中,这样,1号窝没有乌龟,3号窝2只乌龟,4号窝有2只乌龟。
在第二个顾客来时,他想要在3 4号窝中挑选最多10只乌龟,飘飘乎居士将从1号窝调整到4号窝中的2只乌龟以及3号窝剩下的2只乌龟卖出。共卖出7只乌龟,也就是最后的答案。
  
   数据范围:0<n、m<=10
   每个窝初始时乌龟的数量以及每位顾客购买乌龟的数量<=100000
   0<=Pi、qi<=n
   数据保证输入的正确性。
 

 

【思路】

       最大流。

       构图:

       1 对于每个龟窝建立n个结点,建立s t点。

       2 连边:

       (s,ui,twi)        表示龟的数量

     (ui,tmp,INF),(tmp,t,xi)             tmp为中转结点,限制pi个点的总流量

     (qj,qj+1,INF)   表示乌龟的调换

     (ui,ui+1,INF)

 

【代码】

 

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<queue>
  4 #include<vector>
  5 #define FOR(a,b,c) for(int a=(b);a<(c);a++)
  6 using namespace std;
  7 
  8 const int maxn = 500+10;
  9 const int INF = 1e9;
 10 
 11 struct Edge{
 12     int u,v,cap,flow;
 13 };
 14 struct Dinic {
 15     int n,m,s,t;
 16     bool vis[maxn];
 17     int d[maxn],cur[maxn];
 18     vector<int> G[maxn];
 19     vector<Edge> es;
 20     
 21     void init(int n) {
 22         this->n=n;
 23         es.clear();
 24         for(int i=0;i<n;i++) G[i].clear();
 25     }
 26     void AddEdge(int u,int v,int cap) {
 27         es.push_back((Edge){u,v,cap,0});
 28         es.push_back((Edge){v,u,0,0});
 29         m=es.size();
 30         G[u].push_back(m-2);
 31         G[v].push_back(m-1);
 32     }
 33     
 34     bool BFS() {
 35         queue<int> q;
 36         memset(vis,0,sizeof(vis));
 37         q.push(s); vis[s]=1; d[s]=0;
 38         while(!q.empty()) {
 39             int u=q.front(); q.pop();
 40             for(int i=0;i<G[u].size();i++) {
 41                 Edge& e=es[G[u][i]];
 42                 int v=e.v;
 43                 if(!vis[v] && e.cap>e.flow) {
 44                     vis[v]=1;
 45                     d[v]=d[u]+1;
 46                     q.push(v);
 47                 }
 48             }
 49         }
 50         return vis[t];
 51     }
 52     int DFS(int u,int a) {
 53         if(u==t || a==0) return a;
 54         int flow=0,f;
 55         for(int& i=cur[u];i<G[u].size();i++){
 56             Edge& e=es[G[u][i]];
 57             int v=e.v;
 58             if( d[v]==d[u]+1 && (f=DFS(v,min(a,e.cap-e.flow)))>0 ) {
 59                 e.flow+=f;
 60                 es[G[u][i]^1].flow-=f;
 61                 flow+=f,a-=f;
 62                 if(!a) break;
 63             }
 64         }
 65         return flow;
 66     }
 67     int Maxflow(int s,int t) {
 68         this->s=s , this->t=t;
 69         int flow=0;
 70         while(BFS()) {
 71             memset(cur,0,sizeof(cur));
 72             flow+=DFS(s,INF);
 73         }
 74         return flow;
 75     }
 76 } dc;
 77 
 78 int n,m;
 79 int q[maxn];
 80 
 81 int main() {
 82     scanf("%d%d",&n,&m);  m++;
 83     dc.init(n*m+2);
 84     int s=n*m,t=s+1,x;
 85     FOR(i,0,m-1) {
 86         scanf("%d",&x);
 87         dc.AddEdge(s,i,x);
 88     }
 89     int a,b,limit;
 90     FOR(i,0,n) {
 91         scanf("%d%d",&limit,&a);
 92         int tmp=i*m+m-1;            //中转结点
 93         dc.AddEdge(tmp,t,limit);
 94         FOR(j,0,a) {
 95             scanf("%d",&b); b--;
 96             dc.AddEdge(i*m+b,tmp,INF);
 97         }
 98         scanf("%d",&a);
 99         FOR(j,0,a) scanf("%d",&q[j]),q[j]--;
100         if(i<n-1)  FOR(j,0,a-1) {
101             dc.AddEdge(i*m+q[j],(i+1)*m+q[j+1],INF);
102             dc.AddEdge(i*m+q[j+1],(i+1)*m+q[j],INF);
103         }
104     }
105     FOR(i,0,n-1) FOR(j,0,m-1)
106         dc.AddEdge(i*m+j,(i+1)*m+j,INF);
107     int flow=dc.Maxflow(s,t);
108     printf("%d\n",flow);
109     return 0;
110 }

 

posted on 2015-12-20 15:03  hahalidaxin  阅读(228)  评论(0编辑  收藏  举报