BZOJ-2539: [Ctsc2000]丘比特的烦恼

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2539

裸的匹配吧?那就直接跑sap就好了。。。(PS:数据貌似有重复描述缘分的,按后面一个计算)

代码:

b151f8198618367ac431a7a42c738bd4b31ce50b.jpg.png
#include 

#include 

#include 

#include 

#include 

 

using namespace std ;

 

#define MAXN 210

#define inf 0x7fffffff

 

struct edge{

    edge *next ,*pair ;

    int t , f , c ;

}*head[ MAXN ];

 

void Add(int s ,int t ,int f ,int c ){

    edge *p =new( edge );

    p -> t = t , p -> f = f , p -> c = c , p -> next = head[ s ];

    head[ s ]= p ;

}

 

void AddEdge(int s ,int t ,int f ,int c ){

    Add( s , t , f , c ),Add( t , s ,0,- c );

    head[ s ]-> pair = head[ t ], head[ t ]-> pair = head[ s ];

}

 

int S , T ;

 

int value[ MAXN ][ MAXN ], n , k , pos[ MAXN ][2];

string Name[ MAXN ];

 

string Change( string st ){

    string s = st ;

    for(int i =0; i < s.size(  ); i ++)if( s[ i ]>='A'&& s[ i ]<='Z'){

        s[ i ]= s[ i ]+('a'-'A');

    }

    return s ;

}

 

int Find( string s ){

    for(int i =0; i ++< n *2;)if( Name[ i ]== s )return i ;

}

 

bool check(int x0 ,int y0 ,int x1 ,int y1 ,int t0 ,int t1 ){

    if(( x0 - x1 )*( x0 - x1 )+( y0 - y1 )*( y0 - y1 )> k )return false;

    for(int i =0; i ++<2* n ;)if( i != t0 && i != t1 ){

        if( pos[ i ][0]>=min( x0 , x1 )&& pos[ i ][0]<=max( x0 , x1 )){

            if( pos[ i ][1]>=min( y0 , y1 )&& pos[ i ][1]<=max( y0 , y1 )){

                int X1 = pos[ i ][0]- x0 , Y1 = pos[ i ][1]- y0 ;

                int X2 = pos[ i ][0]- x1 , Y2 = pos[ i ][1]- y1 ;

                if( X1 * Y2 == X2 * Y1 )return false;

            }

        }

    }

    return true;

}

 

int dist[ MAXN ], cost =0;

bool f[ MAXN ];

 

int aug(int v ,int flow ){

    if( v == T ){

        cost += dist[ T ]* flow ;

        return flow ;

    }

    int rec =0; f[ v ]=false;

    for( edge *p = head[ v ]; p ; p = p -> next )if( p ->f && f[ p -> t ]&& dist[ p -> t ]== dist[ v ]+ p -> c ){

        int ret =aug( p -> t ,min( flow - rec , p -> f ));

        p -> f -= ret , p -> pair -> f += ret ;

        if(( rec += ret )== flow )return flow ;

    }

    return rec ;

}

 

queue  Q ;

 

bool spfa(  ){

    for(int i =0; i ++< T ;) dist[ i ]=- inf , f[ i ]=false;

    while(! Q.empty(  )) Q.pop(  );

    dist[ S ]=0, Q.push( S ), f[ S ]=true;

    while(! Q.empty(  )){

        int v = Q.front(  ); Q.pop(  ); f[ v ]=false;

        for( edge *p = head[ v ]; p ; p = p -> next )if( p -> f && dist[ p -> t ]< dist[ v ]+ p -> c ){

            dist[ p -> t ]= dist[ v ]+ p -> c ;

            if(! f[ p -> t ]){

                f[ p -> t ]=true; Q.push( p -> t );

            }

        }

    }

    return dist[ T ]>- inf ;

}

 

void costflow(  ){

    while(spfa(  )){

        do{

            memset( f ,true,sizeof( f ));

        }while(aug( S , inf ));

    }

}

 

int main(  ){

    cin >> k >> n ; k *= k ;

    for(int i =0; i ++< n *2;){

        cin >> pos[ i ][0]>> pos[ i ][1]>> Name[ i ];

        Name[ i ]=Change( Name[ i ]);

    }

    for(int i =0; i ++< n *2;)for(int j =0; j ++< n *2;) value[ i ][ j ]=1;

    string s ;

    for( cin >> s ; s !="End"; cin >> s ){

        int x ; string s0 ;

        cin >> s0 >> x ;

        s =Change( s ); s0 =Change( s0 );

        int y =Find( s ), z =Find( s0 );

        value[ y ][ z ]= value[ z ][ y ]= x ;

    }

    memset( head ,0,sizeof( head ));

    S = n *2+1, T = n *2+2;

    for(int i =0; i ++< n ;)AddEdge( S , i ,1,0);

    for(int i = n ; i ++< n *2;)AddEdge( i , T ,1,0);

    for(int i =0; i ++< n ;)for(int j = n ; j ++< n *2;){

        if(check( pos[ i ][0], pos[ i ][1], pos[ j ][0], pos[ j ][1], i , j )){

            AddEdge( i , j ,1, value[ i ][ j ]);

        }

    }

    costflow(  );

    cout << cost << endl ;

    return 0;

}


你可能感兴趣的:(BZOJ-2539: [Ctsc2000]丘比特的烦恼)