题意:c头牛日光浴,有l个区域可以选择。每头牛需要的光照强度区间告诉了,然后每个区域的光强以及可以承载的牛数告诉了,求最大满足的牛数量。
题解:最大流。对于S到每头牛建一条流量为1的边,然后每头牛到它能到的区域建一条流量为1的边,每个区域到T建一条流量为该区域承载牛数量的边。
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 }