最大独立集问题: 在N个点的图G中选出m个点,使
这m个点两两之间没有边.求m最大值.
记住一个重要的结论:
二分图的最大独立集数=节点数(n)-最大匹配数
可以这样理解,在总的点集中,去掉最少的点,使得剩下的点相互之间没有边。用最少的点去覆盖所有的边,也就是最小覆盖。
#include <iostream> #include <stdio.h> #include <string.h> #define MAX 1505 using namespace std; struct node { int u,v,next; }edge[MAX<<1]; int head[MAX],fa[MAX],vis[MAX]; int tot; void init() { memset(head,-1,sizeof(head)); memset(fa,-1,sizeof(fa)); tot=0; } void addedge(int u,int v) { edge[tot].u=u; edge[tot].v=v; edge[tot].next=head[u]; head[u]=tot++; } int dfs(int u) { for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].v; if(!vis[v]) { vis[v]=1; if(fa[v]==-1||dfs(fa[v])) { fa[v]=u; return 1; } } } return 0; } int main() { //freopen("in.txt","r",stdin); int n; while(scanf("%d",&n)!=EOF) { init(); for(int i=0;i<n;i++) { int a,b,c; scanf("%d: (%d) ",&a,&c); while(c--) { scanf("%d",&b); addedge(a,b); } } int res=0; for(int i=0;i<n;i++) { memset(vis,0,sizeof(vis)); res+=dfs(i); } printf("%d\n",n-res/2); } return 0; }