zoukankan      html  css  js  c++  java
  • BZOJ1707: [Usaco2007 Nov]tanning分配防晒霜

    n头牛,第i头要SPF(某个参数)在Lowi到Highi的药,药m种每种SPF为Vi,数量为Numi,求最多能满足几头牛。

    方法一:什么都看不出来,只知道第i头牛能和一些药匹配,于是网络流,牛向药连容量1的边,起点向牛容量1,药向终点容量为药数量,最大流。

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<algorithm>
      4 #include<cstdlib>
      5 #include<cstring>
      6 //#include<iostream>
      7 using namespace std;
      8 
      9 int n,m;
     10 #define maxn 5011
     11 #define maxm 3000011
     12 struct Edge{int from,to,next,cap,flow;};
     13 const int inf=0x3f3f3f3f;
     14 struct Network
     15 {
     16     Edge edge[maxm];int n,le;
     17     int first[maxn],cur[maxn],dis[maxn];
     18     void clear(int n) 
     19     {
     20         this->n=n;le=2;
     21         memset(first,0,sizeof(first));
     22     }
     23     void add_edge(int x,int y,int cap)
     24     {
     25         Edge &e=edge[le];
     26         e.to=y;e.from=x;
     27         e.cap=cap;e.flow=0;
     28         e.next=first[x];
     29         first[x]=le++;
     30     }
     31     void insert(int x,int y,int cap)
     32     {
     33         add_edge(x,y,cap);
     34         add_edge(y,x,0);
     35     }
     36     int s,t;
     37     int que[maxn],head,tail;
     38     bool bfs()
     39     {
     40         memset(dis,0,sizeof(dis));
     41         dis[s]=1;
     42         que[head=(tail=1)-1]=s;
     43         while (head!=tail)
     44         {
     45             const int now=que[head++];
     46             for (int i=first[now];i;i=edge[i].next)
     47             {
     48                 const Edge &e=edge[i];
     49                 if (e.cap>e.flow && !dis[e.to])
     50                 {
     51                     dis[e.to]=dis[now]+1;
     52                     que[tail++]=e.to;
     53                 }
     54             }
     55         }
     56         return dis[t];
     57     }
     58     int dfs(int x,int a)
     59     {
     60         if (x==t || !a) return a;
     61         int flow=0,f;
     62         for (int &i=cur[x];i;i=edge[i].next)
     63         {
     64             Edge &e=edge[i];
     65             if (dis[e.to]==dis[x]+1 && (f=dfs(e.to,min(a,e.cap-e.flow)))>0)
     66             {
     67                 e.flow+=f;
     68                 flow+=f;
     69                 edge[i^1].flow-=f;
     70                 a-=f;
     71                 if (!a) break;
     72             }
     73         }
     74         return flow;
     75     }
     76     int Dinic(int s,int t)
     77     {
     78         this->s=s;this->t=t;
     79         int ans=0;
     80         while (bfs())
     81         {
     82             for (int i=1;i<=n;i++) cur[i]=first[i];
     83             ans+=dfs(s,inf);
     84         }
     85         return ans;
     86     }
     87 }G;
     88 struct Point{int low,high;}a[maxn];
     89 int x;
     90 int main()
     91 {
     92     scanf("%d%d",&n,&m);
     93     G.clear(n+m+2);
     94     int s=n+m+1,t=s+1;
     95     for (int i=1;i<=n;i++) G.insert(s,i,1);
     96     for (int i=1;i<=n;i++) scanf("%d%d",&a[i].low,&a[i].high);
     97     for (int i=1;i<=m;i++)
     98     {
     99         scanf("%d",&x);
    100         for (int j=1;j<=n;j++)
    101             if (a[j].low<=x && a[j].high>=x)
    102                 G.insert(j,i+n,1);
    103         scanf("%d",&x);
    104         G.insert(i+n,t,x);
    105     }
    106     printf("%d
    ",G.Dinic(s,t));
    107     return 0;
    108 }
    View Code

    方法二:考虑两头High不同的牛,High小的能选的药一定不会超过High大的的上界。分类讨论一下Low的情况,可以发现,按High排序后,为了使对后面的影响最小,High小的那些牛应尽量选择spf小的药,因为这些后面的牛不一定选得到;而如果选了某个药导致后面某头牛不能吃药,那对答案是没有影响的,因为他们两头牛选药起冲突了,给谁吃都一样嘛。

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<algorithm>
     4 #include<cstdlib>
     5 #include<cstring>
     6 //#include<iostream>
     7 using namespace std;
     8 
     9 int n,m;
    10 #define maxn 2511
    11 struct Point
    12 {
    13     int low,high;
    14     bool operator < (const Point &a) const {return high<a.high;}
    15 }a[maxn];
    16 struct Bottle
    17 {
    18     int num,v;
    19     bool operator < (const Bottle &a) const {return v<a.v;}
    20 }b[maxn];
    21 int find(int x)
    22 {
    23     int L=1,R=m;
    24     while (L<R)
    25     {
    26         int mid=(L+R)>>1;
    27         if (b[mid].v<x) L=mid+1;
    28         else R=mid;
    29     }
    30     return L;
    31 }
    32 int main()
    33 {
    34     scanf("%d%d",&n,&m);
    35     for (int i=1;i<=n;i++) scanf("%d%d",&a[i].low,&a[i].high);
    36     for (int i=1;i<=m;i++) scanf("%d%d",&b[i].v,&b[i].num);
    37     sort(a+1,a+1+n);
    38     sort(b+1,b+1+m);
    39     int ans=0;
    40     for (int i=1;i<=n;i++)
    41     {
    42         int p=find(a[i].low);
    43         while (p<=m && b[p].v<=a[i].high && !b[p].num) p++;
    44         if (p<=m && b[p].v<=a[i].high) b[p].num--,ans++;
    45     }
    46     printf("%d
    ",ans);
    47     return 0;
    48 }
    View Code

    总觉得网络流和贪心有妙不可言的关系,因为不是第一次见到网络流模型转成贪心问题了。

  • 相关阅读:
    UVa 1451 Average (斜率优化)
    POJ 1160 Post Office (四边形不等式优化DP)
    HDU 3507 Print Article (斜率DP)
    LightOJ 1427 Substring Frequency (II) (AC自动机)
    UVa 10245 The Closest Pair Problem (分治)
    POJ 1741 Tree (树分治)
    HDU 3487 Play with Chain (Splay)
    POJ 2828 Buy Tickets (线段树)
    HDU 3723 Delta Wave (高精度+calelan数)
    UVa 1625 Color Length (DP)
  • 原文地址:https://www.cnblogs.com/Blue233333/p/7151631.html
Copyright © 2011-2022 走看看