HDU 1068 最大独立集

题意是有n个学生,男女之间可能互相喜欢,让你找一个最大的学生集合,使得集合内的学生都不互相喜欢.

思路:显然是找原图补图中最大的子完全图,最大子完全图即最大团,而这个图是二分图,因此即找最大独立集(二分图补图的最大团).

二分图上的一些关系:
|最大独立集| = |V|-|最大匹配数|
|最小点覆盖|=|最大匹配|
有向无环图:|最小路径覆盖|=|V|-|M|
一个二分图不错的链接:
http://blog.csdn.net/whosemario/article/details/8513836

#include<cstdio>
#include<cstring>
#include<ctime>
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
const int N=1e3+5;
int n;
int _map[N][N];
int vis[N];
int match[N];
char s[20];
bool dfs(int u)
{
    for(int i=1;i<=n;i++)if(!vis[i]&&_map[u][i])
    {
        vis[i]=1;
        if(match[i]==-1||dfs(match[i]))
        {
           match[i]=u;
           return true;
        }
    }
    return false;
}
int  main()
{
    //freopen("a.txt","r",stdin);
    while(~scanf("%d",&n))
    {
        memset(_map,0,sizeof(_map));
        for(int i=1;i<=n;i++)
        {
            int id,k;
            scanf("%d: (%d)",&id,&k);
            id++;
            for(int j=1;j<=k;j++)
            {
                int v;
                scanf("%d",&v);v++;
                if(id!=v)
                _map[id][v]=1;
            }
        }
        memset(match,-1,sizeof(match));
        int ans=0;
        for(int i=1;i<=n;i++)
        {
            memset(vis,0,sizeof(vis));
            if(dfs(i))ans++;
        }
        printf("%d\n",n-ans/2);//因为是无向图,每个边算了两次
    }
    return 0;
}

你可能感兴趣的:(二分图)