最小点覆盖=最大二分匹配的 (单向图) ;
最小点覆盖=最大二分匹配的一半 (双向图) ;
所以我们只需求最大匹配,用 匈牙利算法 求出最大匹配,除以二得到答案
具体算法都已经给出相关链接;下面给出自己AC 代码
#include<stdio.h> #include<algorithm> #include<iostream> #include<string> #include<string.h> #include<stdlib.h> using namespace std; typedef long long int LL; const int MAXSIZE=10000; struct Edge { int s,t; }; Edge edge[MAXSIZE]; int first[MAXSIZE],nexts[MAXSIZE]; int link[MAXSIZE]; bool vis[MAXSIZE]; int tot; void init() { memset(first,-1,sizeof(first)); memset(link,-1,sizeof(link)); tot=0; } void addedge(int s,int t) { edge[tot].s=s,edge[tot].t=t; nexts[tot]=first[s]; first[s]=tot; tot++; } int dfs(int now) { for(int i=first[now];i!=-1;i=nexts[i]) { int to=edge[i].t; if(!vis[to]) { vis[to]=true; if(link[to]==-1||dfs(link[to])) { link[to]=now; return 1; } } } return 0; } int max_match(int n) { int ans=0; for(int i=0;i<n;i++) { memset(vis,0,sizeof(vis)); ans+=dfs(i); } return ans; } int main() { int n; while(scanf("%d",&n)+1) { init(); for(int i=0;i<n;i++) { int t1,t2; scanf("%d:(%d)",&t1,&t2); while(t2--) { int num; scanf("%d",&num); addedge(t1,num); addedge(num,t1); } } printf("%d ",max_match(n)>>1); } return 0; }