POJ 3614

题意: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 }

你可能感兴趣的:(poj)