POJ 3692 Kindergarten (补图是二分图的最大团问题)
题意
幼稚园里有m个男孩和n个女孩(m、n范围都是[1,200]),男孩之间相互认识,女孩之间也相互认识,另外有部分男孩和女孩也认识。现在要举办一个活动,选取一些同学,要求所有选取的同学之间两两相互认识。
思路
抽象一下问题就是:在图G中选择一个最大的子图G‘(V', E'),使得∑u, v∈V’, (u, v)∈E‘,这就是最大团问题,也即最大完全子图问题。
一般性的最大团问题是NP问题,但是此题的图比较特殊,有g个点互相相连,b个点也互相相连,也就是说他们的补图是一个二分图。那么我们就可以转化为补图G的最大独立子集:∑u, v∈V,  (u, v)∈E
代码
[cpp]
#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <algorithm>
#include <string>
#include <cstring>
#define MID(x,y) ((x+y)/2)
#define MEM(a,b) memset(a,b,sizeof(a))
#define REP(i, begin, m)   for (int i = begin; i < begin+m; i ++)
using namespace std;
const int MAXV = 405;                   //N1+N2
vector <int> adj[MAXV];
struct MaximumMatchingOfBipartiteGraph{
    int vn;
    void init(int n){                   //二分图两点集点的个数
        vn = n;
        for (int i = 0; i <= vn; i ++)     adj[i].clear();
    }
    void add_uedge(int u, int v){
		adj[u].push_back(v);
		adj[v].push_back(u);
    }
    bool vis[MAXV];
    int mat[MAXV];                      //记录已匹配点的对应点
    bool cross_path(int u){
        for (int i = 0; i < (int)adj[u].size(); i ++){
            int v = adj[u][i];
            if (!vis[v]){
                vis[v] = true;
                if (mat[v] == 0 || cross_path(mat[v])){
                    mat[v] = u;
                    mat[u] = v;
                    return true;
                }
            }
        }
        return false;
    }
    int hungary(){
        MEM(mat, 0);
        int match_num = 0;
        for (int i = 1; i <= vn; i ++){
            MEM(vis, 0);
            if (!mat[i] && cross_path(i)){
                match_num ++;
            }
        }
        return match_num;
    }
	void print_edge(){
        for (int i = 1; i <= vn; i ++){
            for (int j = 0; j < (int)adj[i].size(); j ++){
                printf("u = %d v = %d\n", i, adj[i][j]);
            }
        }
    }
}match;
bool mat[MAXV>>1][MAXV>>1];
int main(){
	//freopen("test.in", "r", stdin);
	//freopen("test.out", "w", stdout);
	int g, b, m;
	int ca = 1;
	while(scanf("%d %d %d", &g, &b, &m), g+b+m){
        match.init(g+b);
        REP(i, 1, g)
            REP(j, 1, b)
                mat[i][j] = true;
        REP(i, 0, m){
            int x, y;
            scanf("%d %d", &x, &y);
            mat[x][y] = false;
        }
        REP(i, 1, g)
            REP(j, 1, b)
                if (mat[i][j])
                    match.add_uedge(i, j+g);
        printf("Case %d: %d\n", ca++, g+b-match.hungary());
	}
	return 0;
}
[/cpp]
POJ 3692 Kindergarten (补图是二分图的最大团问题)的更多相关文章
- POJ 3692 Kindergarten (二分图 最大团)
		Kindergarten Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 5660 Accepted: 2756 Desc ... 
- POJ 3692 Kindergarten(二分图最大独立集)
		题意: 有G个女孩,B个男孩.女孩彼此互相认识,男孩也彼此互相认识.有M对男孩和女孩是认识的.分别是(g1,b1),.....(gm,bm). 现在老师要在这G+B个小孩中挑出一些人,条件是这些人都互 ... 
- POJ 3692 Kindergarten(最大团问题)
		题目链接:http://poj.org/problem?id=3692 Description In a kindergarten, there are a lot of kids. All girl ... 
- POJ 3692 Kindergarten(最大独立集)
		[题目链接] http://poj.org/problem?id=3692 [题目大意] 男生相互之间都认识,女生相互之间也都认识, 一些男生和一些女生相互之间也认识,求找出最多的人参加派对, 他们相 ... 
- poj 3692 Kindergarten
		Kindergarten Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 6956 Accepted: 3436 Desc ... 
- poj 3692 Kindergarten (最大独立集)
		Kindergarten Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 4903 Accepted: 2387 Desc ... 
- poj 3692 Kindergarten (最大独立集之逆匹配)
		Description In a kindergarten, there are a lot of kids. All girls of the kids know each other and al ... 
- POJ 3692:Kindergarten(二分图最大团)
		题目链接 题意 已知班级有g个女孩和b个男孩,所有女生之间都相互认识,所有男生之间也相互认识,给出m对关系表示哪个女孩与哪个男孩认识.现在要选择一些学生来组成一个集合,使得里面所有人都认识,求此集合最 ... 
- POJ 3692:Kindergarten(最大的使命)
		id=3692">Kindergarten Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 4920 Ac ... 
随机推荐
- (转)8 reviews about de novo genome assembly
			转自:http://dskernel.blogspot.com/2012/04/8-reviews-about-de-novo-genome-assembly.html 8 reviews about ... 
- POJ 1969
			#include <iostream> #include <cmath> using namespace std; int main() { //freopen("a ... 
- 23种设计模式学习一(单列模式)singleton
			单列模式的类(单线程下的) class Singleton { private static Singleton instance; private Singleton() { } public st ... 
- lintcode:买卖股票的最佳时机 I
			买卖股票的最佳时机 假设有一个数组,它的第i个元素是一支给定的股票在第i天的价格.如果你最多只允许完成一次交易(例如,一次买卖股票),设计一个算法来找出最大利润. 样例 给出一个数组样例 [3,2,3 ... 
- 欧拉工程第55题:Lychrel numbers
			package projecteuler51to60; import java.math.BigInteger; import java.util.Iterator; import java.util ... 
- Python概述_软件安装_常见问题
			1. Python安装 目前python有2个大版本,2和3,由于2和3语法有差别,现有的许多库都是基于python2开发,本系列文章以python2为主. 1.1 重要概念 1. 动态语言 运行 ... 
- C++语言,统计一篇英文文章中的单词数(用正则表达式实现)
			下面的例子展示了如何在C++11中,利用regex_search()统计一篇英文文章中的单词数: #include <iostream> #include <regex> #i ... 
- eclipse导入的工程前面有感叹号是什么意思
			1.尤其是从其他地方拷贝来并且直接加载的工程,刚打开往往会看到工程的图标上有个红色的感叹号,这是因为build path 出错了,里面有缺失或者无法找到的包. 2. 原因:显示红色感叹号是因为jar包 ... 
- Haproxy安装及配置
			1.安装 # wget http://haproxy.1wt.eu/download/1.3/src/haproxy-1.3.20.tar.gz # tar zcvf haproxy-1.3.20.t ... 
- k序数组排序
			这道题,已知一个数组a,a[i]排好序后位于a[i-k]跟a[i+k]之间,问说该怎么最快地排序. 可以转换成多路归并问题, a[0]<a[k+1]<a[2k+2]<a[3k+3]. ... 
