Poj_2771 Guardian of Decency -最大团

题目: 找出不会恋爱的人的最大独立集。

分析:一眼看下去以为是最大独立集,但是题目给定的边是不会恋爱的边,所以想想会发现其实求最大团。

吐槽:虽然看到500个点,但我没用邻接表,因为求补图的话边会很多,是个稠密图。

/************************************************
Author        :DarkTong
Created Time  :2016/8/1 10:14:42
File Name     :Poj_2771.cpp
*************************************************/

//#include <bits/stdc++.h>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <string>
#include <iostream>
//#define abs(a) a>=0?a:-a
using namespace std;
const int maxn = 500 + 11;
struct Node
{
    int h;
    string se, mu, sp;
}peo[maxn];
//vector<int> w[maxn];
int w[maxn][maxn];
int n, m, Left[maxn];
bool used[maxn];
bool match(int i)
{
    for(int j=1;j<=m;++j) if(w[i][j]&&!used[j])
    {
    //    int v = w[i][j];
        used[j] = true;
        if(!Left[j]||match(Left[j]))
        {
            Left[j] = i;
            return true;
        }
    }
    return false;
}
//返回最大匹配数
int hungary()
{
    int res=0;
    memset(Left, 0, sizeof(Left));
    for(int i=1;i<=n;++i)
    {
        memset(used, 0, sizeof(used));
        if(match(i)) res++;
    }
    return res;
}


int main()
{
    int T, cas=1;
    scanf("%d", &T);
    while(T--)
    {
    //    for(int i=0;i<maxn;++i) w[i].clear();
        memset(w, 0x1, sizeof(w));

        scanf("%d", &n);
        m=n;

        for(int i=1;i<=n;++i) cin>>peo[i].h>>peo[i].se>>peo[i].mu>>peo[i].sp;
        for(int i=1;i<=n;++i)
            for(int j=1;j<=n;++j)
            {
                if(abs((peo[i].h-peo[j].h))>40||peo[i].se==peo[j].se||peo[i].mu!=peo[j].mu||peo[i].sp==peo[j].sp)
                    w[i][j]=0;
                if(i==j) w[i][j]=0;
            //        w[i].push_back(j);
            }
//        cout<<"h:"<<hungary()<<endl;
        printf("%d\n", (2*n-hungary())>>1);

    }
    
    return 0;
}
posted @ 2016-08-01 11:09  DarkTong  阅读(149)  评论(0编辑  收藏  举报