HDU 3829 Cat VS Dog

最大独立集: 在N个点的图G中选出m个点,使这m个点两两之间没有边,求m最大值。如果图G满足二分图条件,则可以用二分图匹配来做。最大独立集点数 = N - 最大匹配数。

这里我们将孩子看成A,B集;

如果A喜欢的动物与B不喜欢的动物相同那么我们就连线;我们就认为第i号人与第j号人相冲突,要么选i号,要么选j号;

因此就成了选取最小点覆盖问题,也就是去除最少的人的冲突;

这里要注意就是要建双向边,因为第i号人与第j号人相冲突必然第j号人与第i号人相冲突;

最大独立集点数 = N - 最大匹配数/2。

 

View Code
#include<iostream>

#include<cstdio>

#include<cstdlib>

#include<algorithm>

#include<cmath>

#include<queue>

#include<set>

#include<map>

#include<cstring>

#include<vector>

using namespace std;

bool visit[524],G[524][524];

int match[524];

bool path( int num , int N )

{

    for( int i = 1 ; i <= N; i ++ )

    {

        if( !visit[i] && G[num][i] )

        {

             visit[i] = true;

             if( match[i]==0 || path( match[i] ,N ) )

             {

                match[i] = num;

                return true;        

             }    

        }    

    }    

    return false;

}

class People

{

public:

       string like,dislike;    

}people[524];

int main(  )

{

    int C,D,N;

    while( scanf( "%d %d %d",&C,&D ,&N )==3 )

    {

        memset( G ,0 , sizeof( G ) );

        memset( match , 0 , sizeof( match ) );

        for( int i =1 ; i <= N ; i ++ )

        {

            cin>>people[i].like>>people[i].dislike;

        }    

        for( int i = 1 ; i <= N ; i++ )

        {

           for( int j = 1 ; j <= N ; j ++ )

           {

                if( people[i].dislike == people[j].like )

                {

                    G[i][j] = true;    

                    G[j][i] = true;

                }    

           }

        }

        int ans = 0;

        for( int i = 1 ; i <= N ; i++ )

        {

            memset( visit , 0 , sizeof( visit ) );

            if( path( i , N ) )

                ans ++;    

        }

        printf( "%d\n",N - ans/2);

    }

    //system( "pause" );

    return 0;

}

 

 

 

你可能感兴趣的:(HDU)