您的位置:首页 > 其它

POJ 1466 Girls and Boys 最大独立集 二分图匹配

2012-04-04 21:57 295 查看
大意就是有n个人,每个人与其他的某几个人有关系,这个关系且称为浪漫关系,然后最后求一个最大的集合,使得集合中所有的人两两之间都不存在浪漫关系。

看到之后就可以发现,这是一道非常明显的最大独立集的问题,可以转化为二分图来做,还是最经典的拆点建图,然后根据定理,最大独立集=顶点数-最小点覆盖数。 而对于这道题来说,我们可以发现这个浪漫关系是相互的。

而我们的建图中,按理来说应该是一边是男的点,一边是女的点这样连边,但是题目中没说性别的问题。

只能将每个点拆成两个点,一个当作是男的点,一个当作是女的点了,然后连边。由于关系是相互的,这样就造成了边的重复。也就是边集是刚才的二倍,从而导致了最大匹配变成了二倍。

那么 ,最大独立集=顶点数-最大匹配/2,所以最终答案就呼之欲出了。

/*
ID: sdj22251
PROG: subset
LANG: C++
*/
#include <iostream>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <cmath>
#include <ctime>
#define MAXN 555
#define MAXM 104444
#define INF 100000000
#define PI acos(-1.0)
#define eps 1e-12
#define L(X) X<<1
#define R(X) X<<1|1
using namespace std;
struct node
{
int v, next;
}edge[MAXN * MAXN];
int e, head[MAXN], mark[MAXN], cx[MAXN], cy[MAXN], n;
void insert(int x, int y)
{
edge[e].v = y;
edge[e].next = head[x];
head[x] = e++;
}
int path(int u)
{
for(int i = head[u]; i != -1; i = edge[i].next)
{
int v = edge[i].v;
if(!mark[v])
{
mark[v] = 1;
if(cy[v] == -1 || path(cy[v]))
{
cx[u] = v;
cy[v] = u;
return 1;
}
}
}
return 0;
}
int solve()
{
int ans = 0;
memset(cx, -1, sizeof(cx));
memset(cy, -1, sizeof(cy));
for(int i = 1; i <= n; i++)
{
memset(mark, 0, sizeof(mark));
ans += path(i);
}
return ans;
}
int main()
{
int x, y, m;
while(scanf("%d", &n) != EOF)
{
e = 0;
memset(head, -1, sizeof(head));
for(int i = 0; i < n; i++)
{
scanf("%d: (%d)", &x, &m);
while(m--)
{
scanf("%d", &y);
insert(x + 1, y + 1);
}
}
int ans = n - solve() / 2;
printf("%d\n", ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: