POJ 3189

被这题坑了多次,就一 二分+二分图多重匹配。

View Code
  1 #include<cstdio>

  2 #include<cstring>

  3 #include<algorithm>

  4 using namespace std;

  5 const int N=1500,M=50000;

  6 int head[N],nc;

  7 struct edge

  8 {

  9     int x,y,next;

 10 } edge[M];

 11 void add(int x,int y)

 12 {

 13     edge[nc].x=x;

 14     edge[nc].y=y;

 15     edge[nc].next=head[x];

 16     head[x]=nc++;

 17 }

 18 int cow[N][25],bar[25];

 19 int lk[25][N],slk[25],co,ba;

 20 bool chk[25];

 21 bool findpath(int x)

 22 {

 23     for(int i=head[x];i!=-1;i=edge[i].next)

 24     {

 25         int t=edge[i].y;

 26         if(!chk[t])

 27         {

 28             chk[t]=true;

 29             if(slk[t]<bar[t])

 30             {

 31                 lk[t][slk[t]++]=x;

 32                 return true;

 33             }

 34             for(int j=0;j<slk[t];j++)

 35             {

 36                 if(findpath(lk[t][j]))

 37                 {

 38                     lk[t][j]=x;

 39                     return true;

 40                 }

 41             }

 42         }

 43     }

 44     return false;

 45 }

 46 bool maxmatch()

 47 {

 48     for(int i=1;i<=co;i++)

 49     {

 50         memset(chk,false,sizeof(chk));

 51         if(!findpath(i))

 52             return false;

 53     }

 54     return true;

 55 }

 56 bool solve(int mid)

 57 {

 58     for(int i=1;i+mid<=ba+1;i++)

 59     {

 60         memset(head,-1,sizeof(head));

 61         nc=0;

 62         for(int j=1;j<=co;j++)

 63             for(int k=0;k<mid;k++)

 64                 add(j,cow[j][i+k]);

 65         memset(slk,0,sizeof(slk));

 66         if(maxmatch())

 67             return true;

 68     }

 69     return false;

 70 }

 71 int main()

 72 {

 73     while(scanf("%d%d",&co,&ba)!=EOF)

 74     {

 75         for(int i=1; i<=co; i++)

 76             for(int j=1;j<=ba;j++)

 77                 scanf("%d",&cow[i][j]);

 78         for(int i=1;i<=ba;i++)

 79         {

 80             scanf("%d",&bar[i]);

 81             if(bar[i]>co)

 82                 bar[i]=co;

 83         }

 84         int ll=1,rr=ba,mid,ans=ba;

 85         while(ll<=rr)

 86         {

 87             mid=(ll+rr)>>1;

 88             if(solve(mid))

 89             {

 90                 ans=mid;

 91                 rr=mid-1;

 92             }

 93             else

 94             {

 95                 ll=mid+1;

 96             }

 97         }

 98         printf("%d\n",ans);

 99     }

100     return 0;

101 }

 

你可能感兴趣的:(poj)