poj 2400 Supervisor, Supervisee

呃,这题也太坑人了吧,受不了了~~ 本来想练练自己的代码正确率的,结果一上午就这样的浪费在这道题上了,伤心了,呜呜~~

首先,是这题的输入格式,做之前看了discuss,知道输入的两个矩阵是相反的,所以并没有在这上面浪费多长时间。然后是输出格式,本来想用一个link数组记录下最优匹配就好了,不由深搜,后来才明白,原来题目是让输出所有符合要求的匹配方式,而用数组记录的只是其中一个,最后,最后,就卡死在了一个点上,直到现在还是不明白为什么那样写是错的,感觉没什么大影响啊~恳求哪位大牛能给与指导~~还有一点就是,这题权值搜索要用负值,如果用正的会超时~~

好吧,下面贴出代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#define maxx  20
#define INF  0xffffff
using namespace std;

int mm[maxx][maxx] ;
int vistx[maxx] , visty[maxx] ;
int lx[maxx] , ly[maxx] ;
int linkx[maxx] ;
int mark[maxx] , f[maxx] ;
int n , s , sum , minn ;

int find ( int x )
{
    int i ;
    vistx[x] = 1;
    for ( i = 1 ; i <= n ; i++ )
    if ( !visty[i] )
    {
        int t = lx[x] + ly[i] - mm[x][i] ;
        if ( t == 0 )
        {
            visty[i] = 1;
            if ( linkx[i] == 0 || find ( linkx[i] ))
            {
                linkx[i] = x;
                return 1;
            }
        }
        else if ( minn > t )
        minn = t ;
    }
    return 0;
}

int KM ()
{
    int i , j , k ;
    memset( lx , 0 , sizeof ( lx ));
    memset( ly , 0 , sizeof ( ly ));
    memset( linkx , 0 , sizeof ( linkx ));
    for ( i = 1 ; i <= n ; i++ )
    for ( j = 1 ; j <= n ; j++ )
    if ( lx[i] < mm[i][j] )
    lx[i] = mm[i][j];
    for ( i = 1; i <= n ; i++ )
    {
        while ( 1 )
        {
            memset( vistx , 0 , sizeof ( vistx ));//呃,就是卡死在这里了,将这两个初始化语句放在while
            memset( visty , 0 , sizeof ( visty ));//里面就对,放到外面就WA了,不知道为什么,这有什么影响吗??
            minn = INF ;
            if ( find ( i ))
            break;
            for ( j = 1; j <= n ; j++ )
            {
                if ( vistx[j] )
                lx[j] -= minn ;
                if ( visty[j] )
                ly[j] += minn ;
            }
        }
    }
    int ss = 0;
    for ( i = 1 ; i <= n ; i++ )
    if ( linkx[i] )
    ss += mm[linkx[i]][i];
    return ss;
}


void dfs (  int step , int ans )//深搜输出所有可能的最优匹配
{
    int  i ;
    if ( ans > sum )
    return ;
    if ( step >n )
    {
        if ( ans != sum )
        return ;
        else
        {
            printf ( "Best Pairing %d\n" , s++ );
            for ( i = 1 ; i <= n ; i++ )
            printf ( "Supervisor %d with Employee %d\n" , i , mark[i] );
            return ;
        }
    }
    else
    {
        for ( i = 1 ; i <= n ; i++ )
        if ( !f[i] )
        {
            f[i] = 1;
            mark[step] = i ;
            dfs ( step+1 , ans - mm[step][i] );
            f[i] = 0;
        }
    }
}

int main()
{
    int cas , i , j , k , x;

    scanf ( "%d" , &cas );
    for ( k = 1 ;  k <= cas ; k++ )
    {
        scanf ( "%d" , &n );
        memset( mm , 0 , sizeof ( mm ));
        for ( i = 1 ; i <= n ; i++ )
        for ( j = 1 ; j <= n ; j++ )
        {
            scanf ( "%d" , &x );
            mm[x][i] -= ( j - 1 );//数组要用负值,否则会超时
        }
        for ( i = 1 ; i <= n ; i++ )
        for ( j = 1 ; j <= n ; j++ )
        {
            scanf ( "%d" , &x );
            mm[i][x] -= ( j - 1 );
        }
        sum = -KM();
        printf ( "Data Set %d, Best average difference: %.6lf\n", k , sum / ( 2.0 * n ));
        s = 1;
        memset( mark , 0 , sizeof ( mark ));
        memset( f , 0 , sizeof ( f ));
        dfs( 1 , 0 );
        printf ( "\n" );
    }
    return 0;
}
原文地址:https://www.cnblogs.com/misty1/p/2509599.html