• 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

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

  • 相关阅读:
    Java 编译器
    ElasticSearch 集群搭建
    致:奋斗路上的自己
    ElasticSearch 简单入门
    char* 和 char* const
    usb虚拟网卡与串口
    usb虚拟网卡与串口
    ethtool处理网卡不断重启
    客车网上订票系统项目--票务管理、前端个人信息修改
    mysql错误号码2003 can't connect to mysql server on 'localhost' (0)解决方案
  • 原文地址:https://www.cnblogs.com/Blue233333/p/7151631.html
Copyright © 2020-2023  润新知