hdu 1068 (二分图最大独立集)

最大独立集问题: 在N个点的图G中选出m个点,使

这m个点两两之间没有边.求m最大值. 



记住一个重要的结论:
 二分图的最大独立集数=节点数(n)-最大匹配数


可以这样理解,在总的点集中,去掉最少的点,使得剩下的点相互之间没有边。用最少的点去覆盖所有的边,也就是最小覆盖。


#include <iostream>
#include <stdio.h>
#include <string.h>
#define MAX 1505
using namespace std;

struct node
{
    int u,v,next;
}edge[MAX<<1];
int head[MAX],fa[MAX],vis[MAX];
int tot;


void init()
{
    memset(head,-1,sizeof(head));
    memset(fa,-1,sizeof(fa));
    tot=0;
}

void addedge(int u,int v)
{
    edge[tot].u=u;
    edge[tot].v=v;
    edge[tot].next=head[u];
    head[u]=tot++;
}

int dfs(int u)
{
    for(int i=head[u];i!=-1;i=edge[i].next)
    {
        int v=edge[i].v;
        if(!vis[v])
        {
            vis[v]=1;
            if(fa[v]==-1||dfs(fa[v]))
            {
                fa[v]=u;
                return 1;
            }
        }
    }
    return 0;
}

int main()
{
    //freopen("in.txt","r",stdin);
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        init();
        for(int i=0;i<n;i++)
        {
            int a,b,c;
            scanf("%d: (%d) ",&a,&c);
            while(c--)
            {
                scanf("%d",&b);
                addedge(a,b);
            }
        }
        int res=0;
        for(int i=0;i<n;i++)
        {
            memset(vis,0,sizeof(vis));
            res+=dfs(i);
        }
        printf("%d\n",n-res/2);
    }
    return 0;
}


你可能感兴趣的:(hdu 1068 (二分图最大独立集))