在一个无向图中,一个守卫可以防御住这个点连的所有边,让你求最少多少个守卫能防御住所有的边。
明显是个裸最小顶点覆盖。(虽然当时没想出来)
最小顶点覆盖 = 最大匹配数/2(因为是无向图,所以要除以2)
#include<vector> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn = 1500; int match[maxn],book[maxn]; vector<int> e[maxn]; int m,n; int dfs(int u) { int i; for(i=0;i<e[u].size();i++) { int t = e[u][i]; if(book[t]==0) { book[t] = 1; if(match[t]==0 || dfs(match[t])) { match[t] = u; return 1; } } } return 0; } int main() { int i,j,t1,t2,sum,k,t; while(scanf("%d",&n)==1) { for(i=0;i<=n;i++) e[i].clear(); sum = 0; for(i=0;i<n;i++) { scanf("%d:(%d)",&t,&k); while(k--) { scanf("%d",&j); e[j].push_back(t); e[t].push_back(j); } } memset(match,0,sizeof(match)); for(i=0;i<n;i++) { memset(book,0,sizeof(book)); if(dfs(i)) sum++; } printf("%d\n",sum/2); } }