Pku1149 PIGS卖锗_tclsm的空间_百度空间

Pku1149 PIGS卖锗

Time Limit:2000MS Memory Limit:165536K
Total Submit:39 Accepted:22
Case Time Limit:1000MS

Description

Emmy在一个养猪场工作。这个养猪场有M个锁着的猪圈,但Emmy并没有钥匙。顾客会到养猪场来买猪,一个接着一个。每一位顾客都会有一些猪圈的钥匙,他们会将这些猪圈打开并买走固定数目的猪。所有顾客有的钥匙和他们需要买猪的数量在事先都告诉了Emmy,于是Emmy要订一个计划,使得卖出去的猪最多。买卖的过程是这样的:一个顾客前来,并打开所有他可以打开的猪圈。然后Emmy从这些猪圈里牵出固定数目的猪卖给顾客(最多只能和顾客需要数相等),并可以重新安排这些开着的猪圈中的猪。
每个猪圈可以存放任意数目的猪。
写一个程序,使得Emmy能够卖出去尽可能多的猪。

Input

{dy}行有两个整数:M和N,表示猪圈数和顾客数。
第二行有M个整数,表示每个猪圈初始时有多少猪。
接下来的N行按照前来的次序描述了每一个顾客,每行的格式如下:
A K1 K2…KA B
A表示该顾客拥有的钥匙数,K1...KA表示每个钥匙所对应的猪圈,B表示该顾客需要购买的猪的数目。

Output

仅包含一个整数,即最多能卖出去的猪的数目。

Sample Input

Sample Output

7

Hint

数据规模
1 ≤ M ≤ 1000
1 ≤ N ≤ 100

            极度郁闷的C++的网络流。。搞了1天发现题目看错了。。买猪的不是把猪圈打开,是交换猪圈中的猪。。连边的话 前面的人可以交换自己打开的猪圈 那么 后面的人可以从前面的人打开的猪圈中拿随意的猪。。所以后面的人连上前面的人一条边就行了。。。

//Writer tclsm
#include <iostream>
using namespace std;

const
                int maxn = 1107, maxm = 1000007 , maxnum = 100000000 , empty = -1;
                int n , m , tot , a[ maxn ] , now[ maxn ] , dep[ maxn ] , zz[ maxn ] , list[ maxn ];
                int y[ maxm ] , opp[ maxm ] , flow[ maxm ] , pre[ maxm ];
                int first , last ;

void cnt ( int fir , int lst , int val , int op )
{
                tot++;
                pre[ tot ] = now[ fir ];
                now[ fir ] = tot;
                y [ tot ] = lst;
                opp[ tot ] = op;
                flow[ tot ] = val;             
}

void cnet( int fir , int lst , int val )
{
                cnt( fir , lst , val , tot+2 );
                cnt( lst , fir , 0 , tot );
}

void init()
{
                int i , j , num , fir , lst;
                scanf( "%d %d" , &m , &n );
                first = n+m+1; last = first+1;
                tot = 0;
                for ( int i = 1 ; i <= m ; i++ ) list[ i ] = i+n;
                for ( int i = 1 ; i <= m ; i++ )
                {
                          scanf( "%d" , &num );
                          cnet( i+n , last , num );
                }
                for ( i = 1 ; i <= n ; i++ )
                {
                    fir = i;
                    for ( scanf( "%d" , &j ) ; j >= 1 ; j-- )
                    {
                           scanf( "%d" , &lst );
                           cnet( fir , list[ lst ] , maxnum );
                           list[ lst ] = fir;
                    }
                    scanf( "%d" , &num );
                    cnet( first , fir , num );
                }
}

int add( int x , int cost )
{
                int res , minn , mark , xx;
                if ( x == last ) return( cost );
                res = 0;
                mark = now[ x ];
                while ( mark > 0 )
                {
                             minn = 0;
                             xx = y[ mark ];
                             if ( ( dep[ x ]+1 == dep[ xx ] ) & ( flow[ mark ] > 0 ) )
                                  minn = add( xx , min( cost , flow[ mark ] ) );
                             flow[ mark ] -= minn;
                             flow[ opp[ mark ] ] += minn;
                             res += minn;
                             cost -= minn;
                             if ( cost <= 0 ) break;
                             mark = pre[ mark ];
                }
                dep[ x ] = empty;
                return( res );
}
            
bool bfs()
{
                int head , tail;
                int x , xx , mark;
                memset( dep , empty , sizeof( dep ) );
                head = 1; tail = 1;
                zz[ 1 ] = first;
                dep[ first ] = 1;
                do
                {
                            x = zz[ head ];
                            mark = now[ x ];
                            while ( mark > 0 )
                            {
                                    xx = y[ mark ];
                                    if ( ( flow[ mark ] > 0 ) & ( dep[ xx ] == empty ) )
                                    {
                                           tail++;
                                           zz[ tail ] = xx ;
                                           dep[ xx ] = dep[ x ]+1;
                                    }
                                    mark = pre[ mark ];
                            }
                            head++;
                }
                while ( head <= tail );
                if ( dep[ last ] > 0 ) return( true );
                return( false );
}
  
void print()
{
                int res;
                res = 0;
                while ( bfs() ) res += add( first , maxnum );
                printf( "%d\n" , res );
}

int main()
{
                init();
                print();
}

 

3 3
3 1 10
2 1 2 2
2 1 3 3
1 2 6


郑重声明:资讯 【Pku1149 PIGS卖锗_tclsm的空间_百度空间】由 发布,版权归原作者及其所在单位,其原创性以及文中陈述文字和内容未经(企业库qiyeku.com)证实,请读者仅作参考,并请自行核实相关内容。若本文有侵犯到您的版权, 请你提供相关证明及申请并与我们联系(qiyeku # qq.com)或【在线投诉】,我们审核后将会尽快处理。
—— 相关资讯 ——