首页 > 其他 > 详细

POJ 3692 Kindergarten(二分图最大独立集)

时间:2014-11-16 00:30:50      阅读:342      评论:0      收藏:0      [点我收藏+]

题意:

有G个女孩,B个男孩。女孩彼此互相认识,男孩也彼此互相认识。有M对男孩和女孩是认识的。分别是(g1,b1),.....(gm,bm)。

现在老师要在这G+B个小孩中挑出一些人,条件是这些人都互相认识。问最多可以挑出多少人。

 

思路:

女孩之间互相认识,男孩之间互相认识,所以我们可以将连边定义为:不认识。即:若两个节点之间有连边,则两个节点互不认识。

故题意即为选出最多的点使得这些点任意两点之间没有连边。即选最少的点覆盖所有边。(二分图最大独立集/二分图最小点覆盖)

 

代码:

vector<int> graph[205];
int cx[205],cy[205];
bool bmask[205];
int G,B,M;
bool mp[205][205];


int findPath(int u){
    int L=graph[u].size();
    rep(i,0,L-1){
        int v=graph[u][i];
        if(!bmask[v]){
            bmask[v]=true;
            if(cy[v]==-1||findPath(cy[v])){
                cy[v]=u;
                cx[u]=v;
                return 1;
            }
        }
    }
    return 0;
}
int MaxMatch(){
    int ans=0;
    rep(i,1,G) cx[i]=-1;
    rep(i,1,B) cy[i]=-1;
    rep(i,1,G) if(cx[i]==-1){
        mem(bmask,false);
        ans+=findPath(i);
    }
    return ans;
}


int main(){
    int tcase=0;
    while(scanf("%d%d%d",&G,&B,&M)!=EOF){
        if(!G && !B && !M) break;

        rep(i,1,G) graph[i].clear();
        mem(mp,false);

        while(M--){
            int x,y;
            scanf("%d%d",&x,&y);
            mp[x][y]=true;
        }
        rep(i,1,G) rep(j,1,B) if(false==mp[i][j]) graph[i].push_back(j);

        int dd=MaxMatch();
        printf("Case %d: %d\n",++tcase,G+B-dd);
    }
}

 

POJ 3692 Kindergarten(二分图最大独立集)

原文:http://www.cnblogs.com/fish7/p/4100811.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!