首页 > 代码库 > 【最小点覆盖】POJ3041-Asteroids
【最小点覆盖】POJ3041-Asteroids
【题目大意】
在n*n的网格上有n个点,每次删除一行或者一列,问至少要删除几次才能删除完全部的这些店?
【思路】
在国庆最后一天到来前,把二分图的三个基本情况【最小点覆盖】【DAG图的最小路径覆盖】和【二分图的最大独立集】全部复习了一遍。
这道题是非常典型的最小点覆盖,指的是用最少的点让每条边都至少和两个集合中的某一个点关联。
最小点覆盖=二分图最大匹配数。
对于这道题而言,我们把横坐标作为集合X,纵坐标作为集合Y,对于点(x,y),由X中的x连向Y中的y。对于每条边,只要x和y中有一个被删除即可,明显的最小点覆盖模型。
十分钟水~
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<vector> 6 using namespace std; 7 const int MAXN=505; 8 vector<int> E[MAXN]; 9 int lk[MAXN],vis[MAXN],n,k; 10 11 int find(int u)12 {13 for (int i=0;i<E[u].size();i++)14 {15 int v=E[u][i];16 if (!vis[v])17 {18 vis[v]=1;19 if (!lk[v]||find(lk[v]))20 {21 lk[v]=u;22 return 1;23 }24 }25 }26 return 0;27 }28 29 void init()30 {31 scanf("%d%d",&n,&k);32 for (int i=1;i<=k;i++)33 {34 int x,y;35 scanf("%d%d",&x,&y);36 E[x].push_back(y);37 }38 }39 40 void solve()41 {42 int ans=0;43 memset(lk,0,sizeof(lk));44 for (int i=1;i<=n;i++)45 {46 memset(vis,0,sizeof(vis));47 if (find(i)) ans++;48 }49 printf("%d",ans);50 } 51 52 int main()53 {54 init();55 solve();56 return 0;57 }
【最小点覆盖】POJ3041-Asteroids
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。