zoukankan      html  css  js  c++  java
  • 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
    ",flow);
    109     return 0;
    110 }
  • 相关阅读:
    顺序表的扩容
    顺序表的插入
    顺序表的构造
    C# ContentType: "application/json" 请求方式传json
    顺序表构造,插入,扩容操作
    顺序表
    线性表
    算法
    数据结构的分类
    什么是数据结构
  • 原文地址:https://www.cnblogs.com/lidaxin/p/5060919.html
Copyright © 2011-2022 走看看