题意:在一群男女同学之间存在”浪漫关系”,且该关系只存在于男同学与女同学之间.现在给出你比如2号学生与4号学生有浪漫关系(但是没给出你到底2号是男同学还是4号是男同学).给出所有的关系,要你求出一个由学生构成的集合,该集合中任意两人都不存在”浪漫关系”.
思路:如果把男同学放左边,女同学放右边,如果男i与女j存在关系,那么左i与右j之间就连一条无向边. 其实最终我们要求的就是该二分图的最大独立集.可是现在问题是题目没有给出谁是男,谁是女的,该如何处理呢?其实很简单,不管三七二十一全部按照平常的方法添加进图,那么这个二分图就可以认为左边有一些男,有一些女的,那么匹配完其实就是左边全为男的,和左边全为女的都匹配了一次,显然这两个答案应该相等,所以最后结果除以2就是左边同一性别的答案。最后用总人数减去这个最大匹配即为该最大独立集。
#include<cstdio>
#include<cstring>
#include<vector>
#include<cmath>
using namespace std;
const int maxn=1000;
struct Max_Match
{
int n,m;
vector<int> g[maxn];
bool vis[maxn];
int left[maxn];
void init(int n)
{
this->n=n;
// this->m=m;
for(int i=1;i<=n;i++) g[i].clear();
memset(left,-1,sizeof(left));
}
bool match(int u)
{
for(int i=0;i<g[u].size();i++)
{
int v=g[u][i];
if(!vis[v])
{
vis[v]=true;
if(left[v]==-1 || match(left[v]))
{
left[v]=u;
return true;
}
}
}
return false;
}
int solve()
{
int ans=0;
for(int i=0;i<n;i++)
{
memset(vis,0,sizeof(vis));
if(match(i)) ans++;
}
return ans;
}
}MM;
int T;
int main()
{
int n,k;
while (scanf("%d",&n)!=EOF)
{
MM.init(n);
for (int i = 1;i<=n;i++)
{
int u,num;
scanf("%d: (%d)",&u,&num);
while (num--)
{
int v;
scanf("%d",&v);
MM.g[u].push_back(v);
// MM.g[v].push_back(u);
}
}
printf("%d\n",n-MM.solve()/2);
}
}