题意:c头牛日光浴,有l个区域可以选择。每头牛需要的光照强度区间告诉了,然后每个区域的光强以及可以承载的牛数告诉了,求最大满足的牛数量。

题解:最大流。对于S到每头牛建一条流量为1的边,然后每头牛到它能到的区域建一条流量为1的边,每个区域到T建一条流量为该区域承载牛数量的边。

View Code
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const int N=6000,M=1000000;
 6 const int inff=1<<29;
 7 int head[N],nc;
 8 struct edge
 9 {
10     int x,y,next;
11     int cap;
12 } edge[M*3];
13 void add(int x,int y,int cap)
14 {
15     edge[nc].x=x;
16     edge[nc].y=y;
17     edge[nc].cap=cap;
18     edge[nc].next=head[x];
19     head[x]=nc++;
20     edge[nc].x=y;
21     edge[nc].y=x;
22     edge[nc].cap=0;
23     edge[nc].next=head[y];
24     head[y]=nc++;
25 }
26 int num[N],h[N],S,T,n;
27 int findpath(int x,int flow)
28 {
29     if(x==T)
30         return flow;
31     int res=flow,pos=n-1;
32     for(int i=head[x]; i!=-1; i=edge[i].next)
33     {
34         int y=edge[i].y;
35         if(h[x]==h[y]+1&&edge[i].cap>0)
36         {
37             int tp=findpath(y,min(edge[i].cap,res));
38             res-=tp;
39             edge[i].cap-=tp;
40             edge[i^1].cap+=tp;
41             if(!res||h[S]==n)
42                 return flow-res;
43         }
44         if(edge[i].cap>0&&h[y]<pos)
45             pos=h[y];
46     }
47     if(res==flow)
48     {
49         num[h[x]]--;
50         if(num[h[x]]==0)
51         {
52             h[S]=n;
53             return flow-res;
54         }
55         h[x]=pos+1;
56         num[h[x]]++;
57     }
58     return flow-res;
59 }
60 int Sap()
61 {
62     memset(h,0,sizeof(h));
63     memset(num,0,sizeof(num));
64     int ans=0;
65     while(h[S]!=n)
66         ans+=findpath(S,inff);
67     return ans;
68 }
69 int cow[3000][2];
70 int main()
71 {
72     int c,l;
73     while(scanf("%d%d",&c,&l)!=EOF)
74     {
75         nc=0;
76         memset(head,-1,sizeof(head));
77         n=c+l+2;
78         S=0,T=n-1;
79         for(int i=1;i<=c;i++)
80             scanf("%d%d",&cow[i][0],&cow[i][1]),add(S,i,1);
81         for(int i=1;i<=l;i++)
82         {
83             int sp,co;
84             scanf("%d%d",&sp,&co);
85             add(i+c,T,co);
86             for(int j=1;j<=c;j++)
87                 if(cow[j][0]<=sp&&cow[j][1]>=sp)
88                     add(j,i+c,1);
89         }
90         printf("%d\n",Sap());
91     }
92     return 0;
93 }