POJ 3692 Kindergarten 最大团->最大独立集

题意:在幼儿园中,男孩们相互认识,女孩们相互认识。但男孩和女孩相互之间只有部分人认识。给出男女孩之间认识的关系。让你求出最多的一组人,使得这组人中每个人都相互认识。

思路:这个题是求二分图中最大团的大小。

我们可以知道:图的最大团 = 补图的最大独立集。

最小顶点覆盖+ 最大独立集 = V(顶点数)

 同时在二分图中,最小顶点覆盖=最大匹配数。

所以我们建立二分图的补图后,求出最大匹配数,再用顶点数减去最大匹配数,就是最终的结果。

代码如下:

#include <cstdio>
#include <cstring>
#include <vector>

using namespace std;


const int MAX = 220;

int from[MAX];
vector<int> G[MAX];
bool tmp[MAX][MAX];
bool used[MAX];
int g,b,m;
int x,y;

bool match(int u)
{
    for(int i = 0, sz = G[u].size(); i < sz; ++i){
        int v = G[u][i];
        if(used[v]) continue;
        used[v] = true;
        if(from[v] == -1 || match(from[v])){
            from[v] = u;
            return true;
        }
    }
    return false;
}

int Hungry(){
    int tot = 0;
    memset(from,-1,sizeof(from));
    for(int i = 1; i <= g; ++i){
        memset(used,0,sizeof(used));
        if(match(i)) tot++;
    }
    return tot;
}

int main(void)
{
    //freopen("input.txt","r",stdin);
    int cas = 1;
    while(scanf("%d %d %d", &g,&b,&m),g||b||m){
        memset(tmp,0,sizeof(tmp));
        for(int i = 0; i < m; ++i){
            scanf("%d %d",&x,&y);
            tmp[x][y] = true;
        }
        for(int i = 1; i <= g; ++i){
            G[i].clear();
            for(int j = 1; j <= b; ++j)
                if(!tmp[i][j])
                    G[i].push_back(j);
        }
        /*for(int i = 1; i <= g; ++i)
            for(int j = 0, sz = G[i].size(); j < sz; ++j)
                printf("%d%c",G[i][j]," \n"[j == sz -1]);
        puts("");*/
       // printf("%d\n",Hungry());
        printf("Case %d: %d\n",cas++,g + b - Hungry());
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值