最大独立集 poj1466

来源:互联网 发布:网络骗局大全微信视频 编辑:程序博客网 时间:2024/05/21 06:29

http://poj.org/problem?id=1466
题意:
有一种关系存在于一个男孩和女孩之间,找出一个集合中任意的男孩和女孩不存在这样的关系。问这个集合的最大人数。
将关系视为一条边,要求一个集合不存在这关系,就表明了集合中的顶点两两不能相连。就是求最大的独立集了。
最大独立集:在G中两两不相连的顶点集合S
最大独立集的点数 + 最小顶点覆盖的点数 = V的个数
二分图中:最小顶点覆盖的点数 = 最大匹配数
因为是两两匹配,又没有明确给出男女,所以最后的最大匹配要除2。

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <queue>#include <vector>using namespace std;#define M 100009int n;vector<int> G[M];bool used[M];int match[M];void init(){    for(int i = 0 ;i < M;i++) G[i].clear();}void add_edge(int u,int v){    G[u].push_back(v);}bool dfs(int u){    for(int i = 0;i < G[u].size();i++)    {        int v = G[u][i];        if(!used[v])        {            used[v] = true;            if(match[v] == -1 || dfs(match[v]))            {                match[v] = u;                return true;            }        }    }    return false;}int b_match(){    int ans = 0;    memset(match,-1,sizeof(match));    for(int i = 0;i < n;i++)    {        memset(used,false,sizeof(used));        if(dfs(i)) ans++;    }    return ans;}int main(){    while(scanf("%d",&n) == 1)    {        init();        for(int i = 0;i < n;i++)        {            int a,num;            scanf("%d: (%d)",&a,&num);            for(int j = 0;j < num;j++)            {                int tmp;                scanf("%d",&tmp);                add_edge(a,tmp+n);                add_edge(tmp+n,a);            }        }        int ans = b_match();        printf("%d\n",(2*n-ans)/2);    }    return 0;}
0 0
原创粉丝点击