/*
translation:
一群男孩女孩,同性之间都相互认识,但是异性之间只有某些人认识彼此。给出相互认识的异性的各自编号。
然后求组成一个小队,这个小队里的人都相互认识。问这个小队最多能有多少人。
solution:
根据 最大独立集合+最小顶点覆盖=点数 以及 二分图当中,最大匹配=最小顶点覆盖即可求出来
note:
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
const int maxn = 400 + 5;
int g, b, m, n;
int match[maxn], relation[maxn][maxn];
bool used[maxn];
vector<int> G[maxn];
typedef pair<int,int> P;
void add_edge(int u, int v)
{
G[u].push_back(v);
G[v].push_back(u);
}
bool dfs(int v)
{
used[v] = true;
for(int i = 0; i < G[v].size(); i++) {
int u = G[v][i], w = match[u];
if(w < 0 || !used[w] && dfs(w)) {
match[v] = u;
match[u] = v;
return true;
}
}
return false;
}
int hangary()
{
int res = 0;
memset(match, -1, sizeof(match));
for(int i = 0; i < n; i++) {
if(match[i] < 0) {
memset(used, 0, sizeof(used));
if(dfs(i)) res++;
}
}
return res;
}
int main()
{
//freopen("in.txt", "r", stdin);
int kase = 0;
while(~scanf("%d%d%d", &g, &b, &m)) {
if(g + b + m == 0) break;
n = g + b;
for(int i = 0; i < maxn; i++) G[i].clear();
memset(relation, 0, sizeof(relation));
int u, v;
for(int i = 0; i < m; i++) {
scanf("%d%d", &u, &v);
u--; v--; v += g;
relation[u][v] = relation[v][u] = 1;
}
for(int i = 0; i < g; i++) {
for(int j = g; j < n; j++) if(!relation[i][j]) {
add_edge(i, j);
}
}
printf("Case %d: %d\n", ++kase, n - hangary());
}
return 0;
}
poj3692(二分图最大独立集)
最新推荐文章于 2021-05-14 11:37:32 发布