POJ 2771 Guardian of Decency(求最大点独立集)

该题反过来想:将所有可能发生恋爱关系的男女配对,那么可以带出去的人数应该等于这个二分图的最大独立集 先要做一下预处理,把不符合要求的双方先求出来, company[i][j]表示i、j四个标准都不符合,即他们可能会成为伴侣。

这里要注意因为x、y集合都是0~n-1,左右对称,所以求最大点独立集的点的个数时,最后还要/2。

接下来就是求最大独立集的点的个数。

最大点独立集+最小点覆盖=点的个数 独立集:在集合中的任意两点都不相邻,即两点间不存在边

 

#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <string.h>
using namespace std;

const int maxnx=510;
const int maxny=510;

int company[maxnx][maxny]; //company[i][j]=1表示i、j四个条件全满足,有可能成为伴侣
int used[maxny];
int cnt,t,n,k;
int matchx[maxny];

struct Person{
    int height;
    int sex; //0代表女,1代表男
    char music[101],sports[101];
}pupil[501];

bool dfsfind(int k){
    for(int i=0;i<n;i++){
        if(company[k][i] && !used[i]){
            used[i]=1;
            if(matchx[i]==-1 || dfsfind(matchx[i])){
                matchx[i]=k;
                return true;
            }
        }
    }
    return false;
}

int hungry(){
    cnt=0;
    memset(matchx,-1,sizeof(matchx));
    for(int j=0;j<n;j++){
        memset(used,0,sizeof(used));
        if(dfsfind(j)){
            cnt++;
        }
    }
    return cnt;

}

void deal(){
    Person p1,p2;
    for(int i=0;i<n;i++){
        for(int j=i;j<n;j++){
            p1=pupil[i];
            p2=pupil[j];
            if((abs(p1.height-p2.height)<=40)&&(p1.sex!=p2.sex)&&(strcmp(p1.music,p2.music)==0)&&(strcmp(p1.sports,p2.sports)!=0)){
                company[i][j]=1;
                company[j][i]=1;
            }
        }
    }

}
int main()
{
    char s1[5];
    scanf("%d",&t);
    for(int q=0;q<t;q++){
        scanf("%d",&n);
        memset(company,0,sizeof(company));

        for(int i=0;i<n;i++){
            scanf("%d%s%s%s",&pupil[i].height,s1,pupil[i].music,pupil[i].sports);
            if(s1[0]=='F')
                pupil[i].sex=0;
            else
                pupil[i].sex=1;
        }
        deal();

        int ans=(2*n-hungry())/2;
        printf("%d\n",ans);


    }
    return 0;
}

 

posted @ 2013-08-25 17:07  辰曦~文若  阅读(302)  评论(0编辑  收藏  举报