poj 3189

来源:互联网 发布:淘宝能处理服装库存么? 编辑:程序博客网 时间:2024/05/17 07:47
开始的时候用二分匹配。。 才知道有多重匹配的东西 还不太会.. 回来用网络流做到 

#include <cstdio>
#include <cstring>
#include <stdio.h>
#include <iostream>
using namespace std;

#pragma comment(linker, "/STACK:1024000000,1024000000")
const int MAXN=10000;

const int inf = 0x7fffffff;

const int s = 0;

struct edge{
       int v,next,w;
}edge[1000000];

int head[2*MAXN],cnt;//for sap

void addedge(int u, int v, int w)
{
     edge[cnt].v = v;
     edge[cnt].w = w;
     edge[cnt].next = head[u];
     head[u] = cnt++;
     edge[cnt].v = u;
     edge[cnt].w = 0;
     edge[cnt].next = head[v];
     head[v] = cnt++;
}

int sap(int t)
{
    //cout << "here" << endl;
    int pre[2*MAXN],cur[2*MAXN],dis[2*MAXN],gap[2*MAXN]; //gap±ê¼Ç¶Ï²ã
    int flow = 0 , aug = inf ,u;
    bool flag;
    for (int i = 0 ; i <= t ; ++i)
    {
        cur[i] = head[i];
        gap[i] = dis[i] = 0;
    }
    gap[s] = t+1;
    u = pre[s] = s;
    while (dis[s] <= t)
    {
          flag = 0 ;
          for (int &j = cur[u] ; ~j ; j = edge[j].next)
          {
              int v = edge[j].v;
              if (edge[j].w > 0 && dis[u] == dis[v]+1)
              {
                   flag = 1;
                   if( edge[j].w < aug )aug = edge[j].w;
                   pre[v] = u;
                   u = v;
                   if (u == t)
                   {
                       flow += aug;
                       while (u != s)
                       {
                             u = pre[u];
                             edge[cur[u]].w -= aug;
                             edge[cur[u]^1].w += aug;
                       }
                       aug = inf;
                   }
                   break;
              }
          }
          if ( flag )continue ;
          int mindis = t+1;
          for (int j = head[u]; ~j ; j = edge[j].next)
          {
              int v = edge[j].v;
              if (edge[j].w > 0 && dis[v] < mindis)
              {
                 mindis = dis[v];
                 cur[u] = j;
              }
          }
          if(--gap[dis[u]] == 0)break;
          gap[ dis[u] = mindis+1 ]++;
          u = pre[u];
    }
    return flow;
}

void init ()
{
     memset (head , -1 , sizeof(head));
     cnt=0;
}

int cow[1002][21];
int barn[21];

int main()
{
    int n , b;
    while (scanf("%d%d", &n , &b )!= EOF )
    {
        for ( int i = 0 ; i < n ;i ++ )
            for ( int j = 0 ; j < b ; j ++ )
                scanf("%d" , &cow[i][j] );
        for ( int i = 0 ; i < b ;i ++ )
            scanf("%d" , &barn[i] );
        int ans = 0;
        for ( int k = 1 ; k <= b ; k++ )
        {
            int flag = 0;
            for ( int i = 0 ; i + k <= b ; i ++ )
            {
                init ();
                for ( int j  = 0 ; j < n ; j ++ )
                {
                    addedge ( 0 , j+1 , 1 );
                    for ( int s = 0 ; s < k ; s ++ )
                    {
                        int temp = cow[j][i+s];
                        addedge ( j+1 , temp+n , 1 );
                        //cout << j+1 << " ***** " << temp +n << endl;
                    }
                }
                for ( int j = 0 ; j < b ; j ++ )
                    addedge ( j+1+n , n+1+b , barn[j] );
                //cout << "here" <<endl;
                if ( sap ( n+1+b ) == n )
                {
                    ans = k;
                    flag = 1;
                    break;
                }
            }
            //cout << "here" <<endl;
            if ( flag ) break;
        }
        printf("%d\n" ,ans);

    }
}