(1)思路:
用匈牙利算法求出最大匹配,然后求出最大独立集 = n - 最大匹配 = n - (最大匹配的点数)/2.
(2)匈牙利算法:
匈牙利算法是用来求解最大匹配算法;
算法的基本思想是寻找图中的增广路径,从一个点开始下一个未匹配点,如果找到下一个未匹配点,
就说明找到了一条新的增广路径,将新的匹配边加入增广路径,然后将之前的匹配边与非匹配边取反,
得到新的增广路径。
如果每次寻找的这个点能够找到新的增广路径,最大匹配的点的数量+1.
(3)代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 1e5+10;
int head[maxn],vis[maxn],pre[maxn],m,n,tot;
struct Node{
int v,nxt;
}cur[maxn<<2];
void Init(){
memset(head,-1,sizeof(head));
tot = 0;
}
void Add(int x,int y){
cur[tot].nxt = head[x];
cur[tot].v = y;
head[x] = tot++;
}
bool dfs(int x){
for(int i=head[x];i!=-1;i=cur[i].nxt){
int y = cur[i].v;
if(vis[y]==0){
vis[y] = 1;
if(pre[y]==-1||dfs(pre[y])){
pre[y] = x;
return true;
}
}
}
return false;
}
int fun(){
memset(pre,-1,sizeof(pre));
int ans = 0;
for(int i=0;i<n;i++){
memset(vis,0,sizeof(vis));
if(dfs(i)) ans++;
}
return ans;
}
int main(void){
while(~scanf("%d",&n)){
Init();
for(int i=0;i<n;i++){
int x,y;
scanf("%d: (%d) ",&x,&y);
for(int j=0;j<y;j++){
int z;scanf("%d",&z);
Add(x,z);
}
}
int ans = n-fun()/2;
printf("%d\n",ans);
}
return 0;
}